From b237bb69b0af6ee2630573a139479400bb9ea973 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Wed, 26 Apr 2017 10:35:19 +0200 Subject: [PATCH] OO-2721: return 409 if the pair user name / provider is already used by an other user --- .../restapi/UserAuthenticationWebService.java | 14 ++++ .../restapi/UserAuthenticationMgmtTest.java | 71 ++++++++++++++++--- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java b/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java index 22f69e18963..6323ed74715 100644 --- a/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java +++ b/src/main/java/org/olat/user/restapi/UserAuthenticationWebService.java @@ -51,6 +51,7 @@ import org.olat.login.auth.OLATAuthManager; import org.olat.restapi.security.RestSecurityHelper; import org.olat.restapi.support.ObjectFactory; import org.olat.restapi.support.vo.AuthenticationVO; +import org.olat.restapi.support.vo.ErrorVO; /** * This web service handles functionalities related to authentication credentials of users. @@ -123,6 +124,8 @@ public class UserAuthenticationWebService { * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_AUTHVO} * @response.representation.401.doc The roles of the authenticated user are not sufficient * @response.representation.404.doc The identity not found + * @response.representation.406.doc Cannot create the authentication for an unkown reason + * @response.representation.409.doc Cannot create the authentication because the authentication username is already used by someone else within the same provider * @param username The username of the user * @param authenticationVO The authentication object to persist * @param request The HTTP request @@ -148,6 +151,17 @@ public class UserAuthenticationWebService { String provider = authenticationVO.getProvider(); String authUsername = authenticationVO.getAuthUsername(); String credentials = authenticationVO.getCredential(); + + Authentication currentAuthentication = baseSecurity.findAuthenticationByAuthusername(authUsername, provider); + if(currentAuthentication != null) { + if(!currentAuthentication.getIdentity().equals(identity)) { + ErrorVO error = new ErrorVO(); + error.setCode("unkown:409"); + error.setTranslation("Authentication name used by: " + currentAuthentication.getIdentity().getUser().getEmail()); + return Response.serverError().status(Status.CONFLICT).entity(error).build(); + } + } + Authentication authentication = baseSecurity.createAndPersistAuthentication(identity, provider, authUsername, credentials, null); if(authentication == null) { return Response.serverError().status(Status.NOT_ACCEPTABLE).build(); diff --git a/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java b/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java index 239a6da52b0..b9532fd73df 100644 --- a/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java +++ b/src/test/java/org/olat/restapi/UserAuthenticationMgmtTest.java @@ -37,6 +37,7 @@ import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.List; +import java.util.UUID; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; @@ -54,7 +55,6 @@ import org.junit.Assert; import org.junit.Test; import org.olat.basesecurity.Authentication; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.BaseSecurityManager; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; @@ -63,6 +63,7 @@ import org.olat.core.logging.Tracing; import org.olat.core.util.Encoder; import org.olat.login.auth.OLATAuthManager; import org.olat.restapi.support.vo.AuthenticationVO; +import org.olat.restapi.support.vo.ErrorVO; import org.olat.test.JunitTestHelper; import org.olat.test.OlatJerseyTestCase; import org.springframework.beans.factory.annotation.Autowired; @@ -83,6 +84,8 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase { @Autowired private DB dbInstance; @Autowired + private BaseSecurity securityManager; + @Autowired private OLATAuthManager authManager; @@ -106,12 +109,11 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase { @Test public void createAuthentications() throws IOException, URISyntaxException { RestConnection conn = new RestConnection(); - BaseSecurity baseSecurity = BaseSecurityManager.getInstance(); - Identity adminIdent = baseSecurity.findIdentityByName("administrator"); + Identity adminIdent = securityManager.findIdentityByName("administrator"); try { - Authentication refAuth = baseSecurity.findAuthentication(adminIdent, "REST-API"); + Authentication refAuth = securityManager.findAuthentication(adminIdent, "REST-API"); if(refAuth != null) { - baseSecurity.deleteAuthentication(refAuth); + securityManager.deleteAuthentication(refAuth); } } catch(Exception e) { // @@ -133,7 +135,7 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase { HttpResponse response = conn.execute(method); assertTrue(response.getStatusLine().getStatusCode() == 200 || response.getStatusLine().getStatusCode() == 201); AuthenticationVO savedAuth = conn.parse(response, AuthenticationVO.class); - Authentication refAuth = baseSecurity.findAuthentication(adminIdent, "REST-API"); + Authentication refAuth = securityManager.findAuthentication(adminIdent, "REST-API"); assertNotNull(refAuth); assertNotNull(refAuth.getKey()); @@ -150,15 +152,64 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase { conn.shutdown(); } + /** + * Check if the REST call return a specific error if the pair authentication user name and provider + * is already used. + * + */ + @Test + public void createAuthentications_checkDuplicate() throws IOException, URISyntaxException { + Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("check-auth-1"); + Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("check-auth-2"); + String authUsername = UUID.randomUUID().toString(); + dbInstance.commitAndCloseSession(); + + RestConnection conn = new RestConnection(); + Assert.assertTrue(conn.login("administrator", "openolat")); + + //set the first authentication + AuthenticationVO vo1 = new AuthenticationVO(); + vo1.setAuthUsername(authUsername); + vo1.setIdentityKey(id1.getKey()); + vo1.setProvider("REST-API"); + vo1.setCredential("credentials"); + URI request1 = UriBuilder.fromUri(getContextURI()).path("/users/" + id1.getName() + "/auth").build(); + HttpPut method1 = conn.createPut(request1, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method1, vo1); + + HttpResponse response1 = conn.execute(method1); + Assert.assertEquals(200, response1.getStatusLine().getStatusCode()); + conn.parse(response1, AuthenticationVO.class); + Authentication refAuth1 = securityManager.findAuthentication(id1, "REST-API"); + Assert.assertNotNull(refAuth1); + Assert.assertEquals(id1, refAuth1.getIdentity()); + + // set the second which duplicates the first + AuthenticationVO vo2 = new AuthenticationVO(); + vo2.setAuthUsername(authUsername); + vo2.setIdentityKey(id2.getKey()); + vo2.setProvider("REST-API"); + vo2.setCredential("credentials"); + URI request2 = UriBuilder.fromUri(getContextURI()).path("/users/" + id2.getName() + "/auth").build(); + HttpPut method2 = conn.createPut(request2, MediaType.APPLICATION_JSON, true); + conn.addJsonEntity(method2, vo2); + + HttpResponse response2 = conn.execute(method2); + Assert.assertEquals(409, response2.getStatusLine().getStatusCode()); + ErrorVO error = conn.parse(response2, ErrorVO.class); + Assert.assertNotNull(error); + + conn.shutdown(); + } + @Test public void deleteAuthentications() throws IOException, URISyntaxException { RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); //create an authentication token - BaseSecurity baseSecurity = BaseSecurityManager.getInstance(); - Identity adminIdent = baseSecurity.findIdentityByName("administrator"); - Authentication authentication = baseSecurity.createAndPersistAuthentication(adminIdent, "REST-A-2", "administrator", "credentials", Encoder.Algorithm.sha512); + Identity adminIdent = securityManager.findIdentityByName("administrator"); + Authentication authentication = securityManager.createAndPersistAuthentication(adminIdent, "REST-A-2", "administrator", "credentials", Encoder.Algorithm.sha512); assertTrue(authentication != null && authentication.getKey() != null && authentication.getKey().longValue() > 0); DBFactory.getInstance().intermediateCommit(); @@ -169,7 +220,7 @@ public class UserAuthenticationMgmtTest extends OlatJerseyTestCase { assertEquals(200, response.getStatusLine().getStatusCode()); EntityUtils.consume(response.getEntity()); - Authentication refAuth = baseSecurity.findAuthentication(adminIdent, "REST-A-2"); + Authentication refAuth = securityManager.findAuthentication(adminIdent, "REST-A-2"); assertNull(refAuth); conn.shutdown(); -- GitLab