Implemented OAuth2 client registration.
Change-Id: I0c51bb1ee031e2a6ff9d0181de7dcb1da53d1d07
diff --git a/full/src/main/java/de/ids_mannheim/korap/constant/ClientType.java b/full/src/main/java/de/ids_mannheim/korap/constant/ClientType.java
new file mode 100644
index 0000000..eb78b40
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/constant/ClientType.java
@@ -0,0 +1,19 @@
+package de.ids_mannheim.korap.constant;
+
+public enum ClientType {
+
+ // EM: from RFC 6749
+
+// Clients capable of maintaining the confidentiality of their
+// credentials (e.g., client implemented on a secure server with
+// restricted access to the client credentials), or capable of secure
+// client authentication using other means.
+ CONFIDENTIAL,
+
+// Clients incapable of maintaining the confidentiality of their
+// credentials (e.g., clients executing on the device used by the
+// resource owner, such as an installed native application or a web
+// browser-based application), and incapable of secure client
+// authentication via any other means.
+ PUBLIC;
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
new file mode 100644
index 0000000..09d801a
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
@@ -0,0 +1,43 @@
+package de.ids_mannheim.korap.dao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.criteria.CriteriaBuilder;
+
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.entity.OAuth2Client;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.ParameterChecker;
+
+@Transactional
+@Repository
+public class OAuth2ClientDao {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ public void registerClient (String id, String secret, String name,
+ ClientType type, String url, String redirectURI)
+ throws KustvaktException {
+ ParameterChecker.checkStringValue(id, "client id");
+ ParameterChecker.checkStringValue(name, "client name");
+ ParameterChecker.checkObjectValue(type, "client type");
+ ParameterChecker.checkStringValue(url, "client url");
+ ParameterChecker.checkStringValue(redirectURI, "client redirect uri");
+
+ OAuth2Client client = new OAuth2Client();
+ client.setId(id);
+ client.setName(name);
+ client.setSecret(secret);
+ client.setType(type);
+ client.setUrl(url);
+ client.setRedirectURI(redirectURI);
+
+ entityManager.persist(client);
+ }
+
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
index 1d48b02..74d5b1a 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -1,6 +1,5 @@
package de.ids_mannheim.korap.dao;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
new file mode 100644
index 0000000..c299a22
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
@@ -0,0 +1,39 @@
+package de.ids_mannheim.korap.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import de.ids_mannheim.korap.constant.ClientType;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author margaretha
+ *
+ */
+@Getter
+@Setter
+@Entity
+@Table(name = "oauth2_client")
+public class OAuth2Client {
+
+ @Id
+ private String id;
+ private String secret;
+ @Enumerated(EnumType.STRING)
+ private ClientType type;
+ @Column(name = "redirect_uri")
+ private String redirectURI;
+ private String url;
+ private String name;
+
+ @Override
+ public String toString () {
+ return "id=" + id + ", secret=" + secret + ", type=" + type + ", name="
+ + name + ", url=" + url + ", redirectURI=" + redirectURI;
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
new file mode 100644
index 0000000..dbfdc2e
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
@@ -0,0 +1,48 @@
+package de.ids_mannheim.korap.service;
+
+import org.apache.commons.validator.routines.UrlValidator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.constant.ClientType;
+import de.ids_mannheim.korap.dao.OAuth2ClientDao;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
+
+@Service
+public class OAuth2ClientService {
+
+ @Autowired
+ private OAuth2ClientDao clientDao;
+ @Autowired
+ private UrlValidator urlValidator;
+ @Autowired
+ private EncryptionIface encryption;
+
+
+ public void registerClient (OAuth2ClientJson clientJson)
+ throws KustvaktException {
+ if (!urlValidator.isValid(clientJson.getUrl())) {
+ throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+ clientJson.getUrl() + " is invalid.", clientJson.getUrl());
+ }
+ if (!urlValidator.isValid(clientJson.getRedirectURI())) {
+ throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+ clientJson.getRedirectURI() + " is invalid.",
+ clientJson.getRedirectURI());
+ }
+
+ String secret = null;
+ if (clientJson.getType().equals(ClientType.CONFIDENTIAL)) {
+ secret = encryption.createToken();
+ }
+
+ String id = encryption.createRandomNumber();
+
+ clientDao.registerClient(id, secret, clientJson.getName(),
+ clientJson.getType(), clientJson.getUrl(),
+ clientJson.getRedirectURI());
+ }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
new file mode 100644
index 0000000..b0b88e4
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
@@ -0,0 +1,59 @@
+package de.ids_mannheim.korap.web.controller;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import com.sun.jersey.spi.container.ResourceFilters;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.service.OAuth2ClientService;
+import de.ids_mannheim.korap.web.FullResponseHandler;
+import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
+import de.ids_mannheim.korap.web.filter.BlockingFilter;
+import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
+
+
+@Controller
+@Path("/client")
+//@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+//@ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+public class OAuthClientController {
+
+ @Autowired
+ private OAuth2ClientService clientService;
+ @Autowired
+ private FullResponseHandler responseHandler;
+
+ /** EM: who can register a client?
+ *
+ * The authorization server SHOULD document the size of any identifier
+ * it issues.
+ *
+ * @param context
+ * @param clientJson
+ * @return
+ */
+ @POST
+ @Path("register")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response registerClient (@Context SecurityContext context,
+ OAuth2ClientJson clientJson) {
+ try {
+ clientService.registerClient(clientJson);
+ }
+ catch (KustvaktException e) {
+ responseHandler.throwit(e);
+ }
+ return Response.ok().build();
+ }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
index b43893b..fdc2046 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
@@ -54,7 +54,6 @@
import de.ids_mannheim.korap.handlers.OAuth2Handler;
import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
import de.ids_mannheim.korap.interfaces.EncryptionIface;
-import de.ids_mannheim.korap.server.KustvaktServer;
import de.ids_mannheim.korap.user.TokenContext;
import de.ids_mannheim.korap.user.User;
import de.ids_mannheim.korap.user.UserDetails;
@@ -74,7 +73,7 @@
*/
//todo: only allow oauth2 access_token requests GET methods?
//todo: allow refresh tokens
-@Path(KustvaktServer.API_VERSION + "/oauth2")
+@Path("/oauth2")
public class OAuthController {
@Autowired
@@ -83,17 +82,18 @@
private OAuth2Handler handler;
@Autowired
private AuthenticationManagerIface controller;
- private EncryptionIface crypto;
+
+// private EncryptionIface crypto;
+ @Autowired
private KustvaktConfiguration config;
public OAuthController () {
- this.handler = new OAuth2Handler(BeansFactory.getKustvaktContext()
- .getPersistenceClient());
+// this.handler = new OAuth2Handler(BeansFactory.getKustvaktContext()
+// .getPersistenceClient());
// this.controller = BeansFactory.getKustvaktContext()
// .getAuthenticationManager();
- this.crypto = BeansFactory.getKustvaktContext().getEncryption();
- this.config = BeansFactory.getKustvaktContext().getConfiguration();
+// this.crypto = BeansFactory.getKustvaktContext().getEncryption();
}
@@ -118,31 +118,31 @@
}
- @POST
- @Path("register")
- @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
- public Response registerClient (@Context SecurityContext context,
- @HeaderParam("Host") String host,
- @QueryParam("redirect_url") String rurl) {
- ClientInfo info = new ClientInfo(crypto.createRandomNumber(),
- crypto.createToken());
- info.setUrl(host);
- if (rurl == null)
- throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
- "Missing parameter!", "redirect_url");
- info.setRedirect_uri(rurl);
- TokenContext ctx = (TokenContext) context.getUserPrincipal();
- String json = "";
- try {
- User user = this.controller.getUser(ctx.getUsername());
- this.handler.getPersistenceHandler().registerClient(info, user);
- json = info.toJSON();
- }
- catch (KustvaktException e) {
- throw kustvaktResponseHandler.throwit(e);
- }
- return Response.ok(json).build();
- }
+// @POST
+// @Path("register")
+// @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+// public Response registerClient (@Context SecurityContext context,
+// @HeaderParam("Host") String host,
+// @QueryParam("redirect_url") String rurl) {
+// ClientInfo info = new ClientInfo(crypto.createRandomNumber(),
+// crypto.createToken());
+// info.setUrl(host);
+// if (rurl == null)
+// throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+// "Missing parameter!", "redirect_url");
+// info.setRedirect_uri(rurl);
+// TokenContext ctx = (TokenContext) context.getUserPrincipal();
+// String json = "";
+// try {
+// User user = this.controller.getUser(ctx.getUsername());
+// this.handler.getPersistenceHandler().registerClient(info, user);
+// json = info.toJSON();
+// }
+// catch (KustvaktException e) {
+// throw kustvaktResponseHandler.throwit(e);
+// }
+// return Response.ok(json).build();
+// }
@GET
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
index ecc00bb..e96ec0a 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
@@ -215,6 +215,8 @@
}
/** Invites group members to join a user-group specified in the JSON object.
+ * Only user-group admins and system admins are allowed.
+ *
* @param securityContext
* @param group UserGroupJson containing groupId and usernames to be invited
* as members
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
new file mode 100644
index 0000000..28a2a6a
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
@@ -0,0 +1,16 @@
+package de.ids_mannheim.korap.web.input;
+
+import de.ids_mannheim.korap.constant.ClientType;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class OAuth2ClientJson {
+
+ // all required for registration
+ private String name;
+ private ClientType type;
+ private String url;
+ private String redirectURI;
+}