dnet-openaire-users/src/main/java/eu/dnetlib/openaire/usermanagement/RegisterServiceServlet.java

421 lines
21 KiB
Java

package eu.dnetlib.openaire.usermanagement;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import eu.dnetlib.openaire.user.pojos.RegisteredService;
import eu.dnetlib.openaire.usermanagement.utils.RegisteredServicesUtils;
import eu.dnetlib.openaire.usermanagement.utils.TokenUtils;
import org.apache.commons.validator.routines.UrlValidator;
import org.apache.http.HttpResponse;
import org.apache.log4j.Logger;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.method.P;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
public class RegisterServiceServlet extends HttpServlet {
private Logger logger = Logger.getLogger(RegisterServiceServlet.class);
public void init(ServletConfig config) throws ServletException {
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
config.getServletContext());
}
@Autowired
private RegisteredServicesUtils registeredServicesUtils;
@Autowired
private TokenUtils tokenUtils;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.
getContext().getAuthentication();
String userid = authentication.getSub();
StringBuilder name = new StringBuilder().append(authentication.getUserInfo().getGivenName().charAt(0));
name.append(authentication.getUserInfo().getFamilyName().charAt(0));
request.getSession().setAttribute("name", name.toString());
String idParam = request.getParameter("id");
if (idParam != null && !idParam.isEmpty()) { // EDIT CASE
System.out.println("In edit");
try {
int id = Integer.parseInt(idParam);
RegisteredService registeredService = registeredServicesUtils.getRegisteredServiceDao().fetchRegisteredServiceById(id);
if (registeredService != null && registeredServicesUtils.isAuthorized(userid, id)) {
ServiceResponse serviceResponse = tokenUtils.getRegisteredService(registeredService.getClientId(), registeredService.getRegistrationAccessToken());
updateFormFields(request, registeredService.getName(), registeredService.getKeyType(), serviceResponse);
} else {
if (registeredService == null) {
System.out.println("No service found!");
request.getSession().setAttribute("message", "Not valid registered service with given id " + id + ".");
response.sendRedirect("./registeredServices");
logger.warn("Not valid registered service with " + id + "id.");
} else {
System.out.println("Not authorized");
request.getSession().setAttribute("message", "Not authorized to edit the registered service with id " + id + ".");
response.sendRedirect("./registeredServices");
logger.warn("Not authorized to edit the service with " + id + "id.");
}
}
} catch (NumberFormatException nfe) {
System.out.println("WRONG FORMAT");
request.getSession().setAttribute("message", "Invalid service id.");
response.sendRedirect("./registeredServices");
logger.error("Invalid service id.", nfe);
} catch (SQLException sqle) {
System.out.println("SQL PROBLEM");
request.getSession().setAttribute("message", "Could not fetch registered service.");
response.sendRedirect("./registeredServices");
logger.error("Could not fetch registered service.", sqle);
}
} else {// NEW SERVICE CASE
//Careful! Redirects in method
request.getSession().setAttribute("first_name", null);
request.getSession().setAttribute("key_type", null);
request.getSession().setAttribute("jwksUri", null);
request.getSession().setAttribute("value", null);
checkNumberOfRegisteredServices(request, response, authentication);
}
response.setContentType("text/html");
request.getRequestDispatcher("./registerService.jsp").include(request, response);
}
private void updateFormFields(HttpServletRequest request, String serviceName, String keyType, ServiceResponse serviceResponse) {
System.out.println("UPDATING FORM");
request.getSession().setAttribute("first_name", serviceName);
System.out.println("Service response URI " + serviceResponse.getJwksUri());
request.getSession().setAttribute("key_type", keyType);
if (keyType != null) {
if (keyType.equals("uri")) {
request.getSession().setAttribute("jwksUri", serviceResponse.getJwksUri());
} else {
Key key;
if (serviceResponse.getJwks() != null) {
key = serviceResponse.getJwks().keys[0];
} else {
key = new Key();
}
System.out.println("Service response keys " + serviceResponse.getJwksUri());
Gson gson = new GsonBuilder().setPrettyPrinting().create();
request.getSession().setAttribute("value", gson.toJson(key));
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OIDCAuthenticationToken authentication = (OIDCAuthenticationToken) SecurityContextHolder.
getContext().getAuthentication();
response.setContentType("text/html");
boolean canProceed = true;
String mode = request.getParameter("mode").trim();
System.out.println("Mode was " + mode);
checkmode(mode);
System.out.println("Mode is " + mode);
String serviceId = request.getParameter("id");
String name = request.getParameter("first_name").trim();
if (name.isEmpty()) {
request.getSession().setAttribute("first_name_error", true);
canProceed = false;
}
String keyType = request.getParameter("key_type");
String jwksUri = null;
String jwksString = null;
Jwks jwks = null;
if(keyType != null) {
keyType = keyType.trim();
if (keyType.equals("uri")) {
jwksUri = request.getParameter("uri");
request.getSession().setAttribute("jwksUri", jwksUri);
String[] schemes = {"https"};
UrlValidator urlValidator = new UrlValidator(schemes);
if (!urlValidator.isValid(jwksUri)) {
request.getSession().setAttribute("uri_error", true);
canProceed = false;
}
} else {
jwksString = request.getParameter("value");
try {
Gson gson = new GsonBuilder().registerTypeAdapter(Jwks.class, new JwksDeserializer()).create();
String jwksSet = String.format("{\"keys\":[%s]}", jwksString);
jwks = gson.fromJson(jwksSet, Jwks.class);
request.getSession().setAttribute("value", jwksString);
if (jwks.getKeys() == null || jwks.getKeys().length == 0) {
System.out.println("Something wrong with the keys.");
request.getSession().setAttribute("value_error", true);
canProceed = false;
}
} catch (JsonParseException jpe) {
request.getSession().setAttribute("value_error", true);
canProceed = false;
}
}
}
String userid = authentication.getSub();
String email = authentication.getUserInfo().getEmail();
ServiceResponse serviceResponse = null;
if (nameIsValid(name) && userInfoIsValid(userid, email) && keyIsValid(keyType, jwksUri, jwksString) && canProceed) {
String serverMessage;
if (mode.equals("create")) {
//Careful! Redirects in method
checkNumberOfRegisteredServices(request, response, authentication);
String serverRequestJSON = null;
if(keyType == null) {
serverRequestJSON = createServiceJson(null, name, email);
} else if (keyType.equals("uri")) {
serverRequestJSON = createServiceJson(null, name, email, jwksUri);
} else if (keyType.equals("value")){
serverRequestJSON = createServiceJson(null, name, email, jwks);
}
if(serverRequestJSON != null) {
System.out.println("SERVER JSON " + serverRequestJSON);
serverMessage = tokenUtils.registerService(serverRequestJSON);
logger.debug(serverMessage);
if (serverMessage == null) {
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
serviceResponse = new Gson().fromJson(serverMessage, ServiceResponse.class);
String client_id = serviceResponse.getClientId();
RegisteredService registeredService = new RegisteredService(client_id, userid, name, serviceResponse.getRegistrationAccessToken(), keyType);
try {
registeredServicesUtils.addRegistedService(registeredService);
if(registeredService.getKeyType() != null) {
request.getSession().setAttribute("success",
"Your service has been successfully registered!<br>" +
"<b>Client ID<b>: " + serviceResponse.getClientId());
} else {
request.getSession().setAttribute("success",
"Your service has been successfully registered!<br>" +
"<b>Client ID</b>: " + serviceResponse.getClientId() +
"<br><span style=\"word-wrap: break-word\"><b>Client Secret</b>:" + serviceResponse.getClientSecret() + "</span>");
}
} catch (SQLException sqle) {
logger.error("Fail to save service.", sqle);
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
} else {
logger.error("Service request JSON is null");
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
} else {
int serviceIdInt = 0;
if (serviceId == null || serviceId.isEmpty()) { //TODO WRONG MESSAGE
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
response.sendRedirect("./registeredServices");
} else {
System.out.println("In edit...");
try {
serviceIdInt = Integer.parseInt(serviceId);
if (!registeredServicesUtils.isAuthorized(authentication.getSub(), serviceIdInt)) {
request.getSession().setAttribute("message", "You have no permission to edit the service.");
response.sendRedirect("./registeredServices");
}
RegisteredService registeredService = registeredServicesUtils.getRegisteredServiceDao().fetchRegisteredServiceById(serviceIdInt);
if (registeredService != null && registeredService.getClientId() != null) {
String serverRequestJSON = null;
if (keyType == null) {
serverRequestJSON = createServiceJson(registeredService.getClientId(), name, email);
} else if (keyType.equals("uri")) {
serverRequestJSON = createServiceJson(registeredService.getClientId(), name, email, jwksUri);
} else if (keyType.equals("value")) {
serverRequestJSON = createServiceJson(registeredService.getClientId(), name, email, jwks);
}
if (serverRequestJSON != null) {
System.out.println("SERVER JSON " + serverRequestJSON);
HttpResponse resp = tokenUtils.updateService(registeredService.getClientId(), serverRequestJSON, registeredService.getRegistrationAccessToken());
if (resp.getStatusLine().getStatusCode() == 200) {
System.out.println("NAME >>>>" + name);
registeredService.setName(name);
System.out.println("Client Id " + registeredService.getClientId());
try {
registeredServicesUtils.getRegisteredServiceDao().update(registeredService);
} catch (SQLException sqle) {
logger.error("Unable to contact db.", sqle);
request.getSession().setAttribute("message", "Fail to delete the service. Please try again later.");
response.setContentType("text/html");
request.getRequestDispatcher("./registeredServices.jsp").include(request, response);
return;
}
request.getSession().setAttribute("success",
"Your service has been successfully updated!<br>" +
"<b>Client ID</b>: " + registeredService.getClientId());
}
} else {
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
response.sendRedirect("./registeredServices");
return;
}
} else {
logger.error("Service request JSON is null");
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
} catch(SQLException sqle){
logger.error("Unable to access service with id " + serviceId, sqle);
request.getSession().setAttribute("message", "There was an error accessing your service.");
response.sendRedirect("./registeredServices");
} catch(NumberFormatException nfe){
logger.error("Unable to access service with id " + serviceId, nfe);
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
response.sendRedirect("./registeredServices");
}
}
}
} else {
//something is wrong with the form and the error messages will appear
request.getSession().setAttribute("first_name", name);
request.getSession().setAttribute("key_type", keyType);
request.getSession().setAttribute("uri", jwksUri);
request.getSession().setAttribute("value", jwksString);
if (serviceId != null && !serviceId.isEmpty()) {
request.getRequestDispatcher("./registerService.jsp?id=" + serviceId).forward(request, response);
} else {
request.getRequestDispatcher("./registerService.jsp").include(request, response);
}
return;
}
response.sendRedirect("./registeredServices");
}
private void checkmode(String mode) {
if (mode != null && !mode.isEmpty()) {
if (!mode.equals("edit") || mode.equals("create")) {
mode = "create";
}
} else {
mode = "create";
}
}
private boolean keyIsValid(String keyType, String jwksUri, String jwksString) {
return keyType == null || (keyType.equals("uri") && jwksUri != null && !jwksUri.isEmpty()) ||
keyType.equals("value") && jwksString != null && !jwksString.isEmpty();
}
private boolean userInfoIsValid(String userid, String email) {
return userid != null && !userid.isEmpty() &&
email != null && !email.isEmpty();
}
private boolean nameIsValid(String name) {
return name != null && !name.isEmpty();
}
private void checkNumberOfRegisteredServices(HttpServletRequest request, HttpServletResponse response, OIDCAuthenticationToken authentication) throws IOException {
try {
long numberOfRegisteredServices =
registeredServicesUtils.getRegisteredServiceDao().countRegisteredServices(authentication.getSub());
if (numberOfRegisteredServices >= 5) {
response.sendRedirect("./registeredServices"); // The message there already exists.
}
} catch (SQLException sqle) {
logger.error("Unable to count registered services.", sqle);
request.getSession().setAttribute("message", "Unable to contact DB. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
}
private static String createServiceJson(String clientId, String name, String email) {
ServiceRequest serviceJSON = new ServiceRequest();
serviceJSON.setClientId(clientId);
serviceJSON.setClientName(name);
serviceJSON.setContacts(new String[]{email});
serviceJSON.setToken_endpoint_auth_method("client_secret_basic");
serviceJSON.setTokenEndpointAuthSigningAlg(null);
GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
System.out.println("Created json " + serviceJSON);
return gson.toJson(serviceJSON);
}
private static String createServiceJson(String clientId, String name, String email, String jwksURI) {
ServiceRequest serviceJSON = new ServiceRequest();
serviceJSON.setClientId(clientId);
serviceJSON.setClientName(name);
serviceJSON.setContacts(new String[]{email});
serviceJSON.setJwksUri(jwksURI);
GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
System.out.println("Created json " + serviceJSON);
return gson.toJson(serviceJSON);
}
private static String createServiceJson(String clientId, String name, String email, Jwks jwks) {
ServiceRequest serviceJSON = new ServiceRequest();
serviceJSON.setClientId(clientId);
serviceJSON.setClientName(name);
serviceJSON.setContacts(new String[]{email});
serviceJSON.setJwks(jwks);
GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
System.out.println("Created json " + serviceJSON);
return gson.toJson(serviceJSON);
}
}