Fixed problem with multiple desktop apps
Change-Id: I3443582caecf9d386d74e4fcc9d5917a06be9499
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java
index 9c421fd..19aec7c 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/OAuth2ClientDao.java
@@ -44,9 +44,8 @@
private EntityManager entityManager;
public void registerClient (String id, String secretHashcode, String name,
- OAuth2ClientType type, String url, int urlHashCode,
- String redirectURI, String registeredBy, String description)
- throws KustvaktException {
+ OAuth2ClientType type, String url, String redirectURI,
+ String registeredBy, String description) throws KustvaktException {
ParameterChecker.checkStringValue(id, "client id");
ParameterChecker.checkStringValue(name, "client name");
ParameterChecker.checkObjectValue(type, "client type");
@@ -62,7 +61,6 @@
client.setSecret(secretHashcode);
client.setType(type);
client.setUrl(url);
- client.setUrlHashCode(urlHashCode);
client.setRedirectURI(redirectURI);
client.setRegisteredBy(registeredBy);
client.setDescription(description);
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/OAuth2Client.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/OAuth2Client.java
index 1d7b200..fb5cbbb 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/OAuth2Client.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/OAuth2Client.java
@@ -38,8 +38,6 @@
private String description;
private String url;
- @Column(name = "url_hashcode")
- private int urlHashCode;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "client")
private List<RefreshToken> refreshTokens;
@@ -132,11 +130,4 @@
this.url = url;
}
- public int getUrlHashCode () {
- return urlHashCode;
- }
-
- public void setUrlHashCode (int urlHashCode) {
- this.urlHashCode = urlHashCode;
- }
}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
index a4188c8..6624cf9 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
@@ -85,9 +85,7 @@
ParameterChecker.checkNameValue(clientJson.getName(), "clientName");
String url = clientJson.getUrl();
- int urlHashCode = 0;
if (url != null && !url.isEmpty()) {
- urlHashCode = clientJson.getUrl().hashCode();
if (!urlValidator.isValid(url)) {
throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
url + " is invalid.", OAuth2Error.INVALID_REQUEST);
@@ -125,8 +123,8 @@
String id = codeGenerator.createRandomCode();
try {
clientDao.registerClient(id, secretHashcode, clientJson.getName(),
- clientJson.getType(), url, urlHashCode, redirectURI,
- registeredBy, clientJson.getDescription());
+ clientJson.getType(), url, redirectURI, registeredBy,
+ clientJson.getDescription());
}
catch (Exception e) {
Throwable cause = e;
diff --git a/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql b/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql
index 3245040..6ec4b80 100644
--- a/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql
+++ b/full/src/main/resources/db/sqlite/V1.1__create_virtual_corpus_tables.sql
@@ -3,7 +3,7 @@
name VARCHAR(100) NOT NULL
);
-CREATE UNIQUE INDEX role_index on role(name);
+CREATE UNIQUE INDEX IF NOT EXISTS role_index on role(name);
CREATE TABLE IF NOT EXISTS privilege (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -14,7 +14,7 @@
ON DELETE CASCADE
);
-CREATE UNIQUE INDEX privilege_index on privilege(name, role_id);
+CREATE UNIQUE INDEX IF NOT EXISTS privilege_index on privilege(name, role_id);
CREATE TABLE IF NOT EXISTS user_group (
@@ -26,8 +26,8 @@
deleted_by VARCHAR(100) DEFAULT NULL
);
-CREATE INDEX user_group_index ON user_group(status);
-CREATE UNIQUE INDEX user_group_name on user_group(name);
+CREATE INDEX IF NOT EXISTS user_group_index ON user_group(status);
+CREATE UNIQUE INDEX IF NOT EXISTS user_group_name on user_group(name);
CREATE TABLE IF NOT EXISTS user_group_member (
@@ -44,9 +44,9 @@
ON DELETE CASCADE
);
-CREATE UNIQUE INDEX user_group_member_index
+CREATE UNIQUE INDEX IF NOT EXISTS user_group_member_index
ON user_group_member(user_id,group_id);
-CREATE INDEX user_group_member_status_index
+CREATE INDEX IF NOT EXISTS user_group_member_status_index
ON user_group_member(status);
CREATE TABLE IF NOT EXISTS group_member_role (
@@ -61,7 +61,7 @@
ON DELETE CASCADE
);
-CREATE UNIQUE INDEX group_member_role_index
+CREATE UNIQUE INDEX IF NOT EXISTS group_member_role_index
ON group_member_role(group_member_id,role_id);
@@ -79,9 +79,9 @@
is_cached BOOLEAN DEFAULT 0
);
-CREATE INDEX virtual_corpus_owner_index ON virtual_corpus(created_by);
-CREATE INDEX virtual_corpus_type_index ON virtual_corpus(type);
-CREATE UNIQUE INDEX virtual_corpus_unique_name
+CREATE INDEX IF NOT EXISTS virtual_corpus_owner_index ON virtual_corpus(created_by);
+CREATE INDEX IF NOT EXISTS virtual_corpus_type_index ON virtual_corpus(type);
+CREATE UNIQUE INDEX IF NOT EXISTS virtual_corpus_unique_name
ON virtual_corpus(name,created_by);
CREATE TABLE IF NOT EXISTS virtual_corpus_access (
@@ -100,8 +100,8 @@
ON DELETE CASCADE
);
-CREATE INDEX virtual_corpus_status_index
+CREATE INDEX IF NOT EXISTS virtual_corpus_status_index
ON virtual_corpus_access(status);
-CREATE UNIQUE INDEX virtual_corpus_access_unique_index
+CREATE UNIQUE INDEX IF NOT EXISTS virtual_corpus_access_unique_index
ON virtual_corpus_access(virtual_corpus_id,user_group_id);
diff --git a/full/src/main/resources/db/sqlite/V1.2__triggers.sql b/full/src/main/resources/db/sqlite/V1.2__triggers.sql
index 63dfeae..d2e9b6d 100644
--- a/full/src/main/resources/db/sqlite/V1.2__triggers.sql
+++ b/full/src/main/resources/db/sqlite/V1.2__triggers.sql
@@ -1,18 +1,18 @@
-CREATE TRIGGER insert_member_status AFTER INSERT ON user_group_member
+CREATE TRIGGER IF NOT EXISTS insert_member_status AFTER INSERT ON user_group_member
BEGIN
UPDATE user_group_member
SET status_date = DATETIME('now', 'localtime')
WHERE rowid = new.rowid;
END;
-CREATE TRIGGER update_member_status AFTER UPDATE ON user_group_member
+CREATE TRIGGER IF NOT EXISTS update_member_status AFTER UPDATE ON user_group_member
BEGIN
UPDATE user_group_member
SET status_date = (datetime('now','localtime'))
WHERE rowid = old.rowid;
END;
-CREATE TRIGGER delete_member AFTER UPDATE ON user_group
+CREATE TRIGGER IF NOT EXISTS delete_member AFTER UPDATE ON user_group
WHEN new.status = "DELETED" AND old.status <> "DELETED"
BEGIN
UPDATE user_group_member
diff --git a/full/src/main/resources/db/sqlite/V1.3__create_admin_table.sql b/full/src/main/resources/db/sqlite/V1.3__create_admin_table.sql
index 35b934b..5066799 100644
--- a/full/src/main/resources/db/sqlite/V1.3__create_admin_table.sql
+++ b/full/src/main/resources/db/sqlite/V1.3__create_admin_table.sql
@@ -3,4 +3,4 @@
user_id VARCHAR(100) NOT NULL
);
-CREATE UNIQUE INDEX admin_index on admin(user_id);
\ No newline at end of file
+CREATE UNIQUE INDEX IF NOT EXISTS admin_index on admin(user_id);
\ No newline at end of file
diff --git a/full/src/main/resources/db/sqlite/V1.4__oauth2_tables.sql b/full/src/main/resources/db/sqlite/V1.4__oauth2_tables.sql
index abb9199..58b8ccf 100644
--- a/full/src/main/resources/db/sqlite/V1.4__oauth2_tables.sql
+++ b/full/src/main/resources/db/sqlite/V1.4__oauth2_tables.sql
@@ -10,11 +10,11 @@
redirect_uri TEXT DEFAULT NULL,
description VARCHAR(255) NOT NULL,
registered_by VARCHAR(100) NOT NULL,
- url_hashcode INTEGER,
+ --url_hashcode INTEGER,
url TEXT DEFAULT NULL
);
-CREATE UNIQUE INDEX client_url_index on oauth2_client(url_hashcode);
+--CREATE UNIQUE INDEX client_url_index on oauth2_client(url_hashcode);
CREATE TABLE IF NOT EXISTS oauth2_access_scope (
id VARCHAR(100) PRIMARY KEY NOT NULL
@@ -67,7 +67,7 @@
ON DELETE CASCADE
);
-CREATE TABLE oauth2_refresh_token_scope (
+CREATE TABLE IF NOT EXISTS oauth2_refresh_token_scope (
token_id INTEGER NOT NULL,
scope_id VARCHAR(100) NOT NULL,
CONSTRAINT primary_key PRIMARY KEY (token_id, scope_id)
@@ -90,7 +90,7 @@
REFERENCES oauth2_refresh_token(id)
);
-CREATE TABLE oauth2_access_token_scope (
+CREATE TABLE IF NOT EXISTS oauth2_access_token_scope (
token_id INTEGER NOT NULL,
scope_id VARCHAR(100) NOT NULL,
CONSTRAINT primary_key PRIMARY KEY (token_id, scope_id)
diff --git a/full/src/main/resources/db/sqlite/V1.7__query_references.sql b/full/src/main/resources/db/sqlite/V1.7__query_references.sql
index 0ebdbc1..9d33270 100644
--- a/full/src/main/resources/db/sqlite/V1.7__query_references.sql
+++ b/full/src/main/resources/db/sqlite/V1.7__query_references.sql
@@ -13,4 +13,4 @@
CREATE INDEX query_reference_owner_index ON query_reference(created_by);
CREATE INDEX query_reference_type_index ON query_reference(type);
CREATE UNIQUE INDEX query_reference_unique_name
- ON query_reference(name,created_by);
+ ON query_reference(name,created_by);
\ No newline at end of file
diff --git a/full/src/main/resources/db/sqlite/V1.8__oauth2_alteration.sql b/full/src/main/resources/db/sqlite/V1.8__oauth2_alteration.sql
new file mode 100644
index 0000000..3c0eaaa
--- /dev/null
+++ b/full/src/main/resources/db/sqlite/V1.8__oauth2_alteration.sql
@@ -0,0 +1,3 @@
+-- ND:2020-04-15
+-- Needs to be dropped as null-URLs result in non-unique hash codes
+DROP INDEX IF EXISTS client_url_index;
\ No newline at end of file
diff --git a/full/src/main/resources/db/test/V3.5__insert_oauth2_clients.sql b/full/src/main/resources/db/test/V3.5__insert_oauth2_clients.sql
index d179fdc..fb70f79 100644
--- a/full/src/main/resources/db/test/V3.5__insert_oauth2_clients.sql
+++ b/full/src/main/resources/db/test/V3.5__insert_oauth2_clients.sql
@@ -2,50 +2,50 @@
-- plain secret value is "secret"
INSERT INTO oauth2_client(id,name,secret,type,super,
- redirect_uri,registered_by, description, url, url_hashcode)
+ redirect_uri,registered_by, description, url)
VALUES ("fCBbQkAyYzI4NzUxMg","super confidential client",
"$2a$08$vi1FbuN3p6GcI1tSxMAoeuIYL8Yw3j6A8wJthaN8ZboVnrQaTwLPq",
"CONFIDENTIAL", 1,
"https://korap.ids-mannheim.de/confidential/redirect", "system",
"This is a test super confidential client.",
- "http://korap.ids-mannheim.de/confidential", 2087150261);
+ "http://korap.ids-mannheim.de/confidential");
-- plain secret value is "secret"
INSERT INTO oauth2_client(id,name,secret,type,super,
- redirect_uri,registered_by, description,url,url_hashcode)
+ redirect_uri,registered_by, description,url)
VALUES ("9aHsGW6QflV13ixNpez","non super confidential client",
"$2a$08$vi1FbuN3p6GcI1tSxMAoeuIYL8Yw3j6A8wJthaN8ZboVnrQaTwLPq",
"CONFIDENTIAL", 0,
"https://third.party.com/confidential/redirect", "system",
"This is a test nonsuper confidential client.",
- "http://third.party.com/confidential", 1712550103);
+ "http://third.party.com/confidential");
INSERT INTO oauth2_client(id,name,secret,type,super,
- redirect_uri,registered_by, description,url,url_hashcode)
+ redirect_uri,registered_by, description,url)
VALUES ("52atrL0ajex_3_5imd9Mgw","confidential client 2",
"$2a$08$vi1FbuN3p6GcI1tSxMAoeuIYL8Yw3j6A8wJthaN8ZboVnrQaTwLPq",
"CONFIDENTIAL", 0,
"https://example.client.de/redirect", "system",
"This is a test nonsuper confidential client.",
- "http://example.client.de", 1535365678);
+ "http://example.client.de");
INSERT INTO oauth2_client(id,name,secret,type,super,
- redirect_uri, registered_by, description, url,url_hashcode)
+ redirect_uri, registered_by, description, url)
VALUES ("8bIDtZnH6NvRkW2Fq","third party client",null,
"PUBLIC", 0,
"https://third.party.client.com/redirect","system",
"This is a test public client.",
- "http://third.party.client.com", -2137275617);
+ "http://third.party.client.com");
INSERT INTO oauth2_client(id,name,secret,type,super,
- redirect_uri, registered_by, description,url,url_hashcode)
+ redirect_uri, registered_by, description,url)
VALUES ("nW5qM63Rb2a7KdT9L","test public client",null,
"PUBLIC", 0,
"https://korap.ids-mannheim.de/public/redirect","system",
"This is a test public client.",
- "http://korap.ids-mannheim.de/public", 1360724310);
+ "http://korap.ids-mannheim.de/public");
INSERT INTO oauth2_access_token(token,user_id,created_date,
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
index 3183beb..a8acf4e 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
@@ -135,7 +135,7 @@
assertNotNull(clientId);
assertNotNull(clientSecret);
- testRegisterClientNonUniqueURL();
+// testRegisterClientNonUniqueURL();
testResetConfidentialClientSecret(clientId, clientSecret);
// testDeregisterConfidentialClientMissingSecret(clientId);
@@ -143,6 +143,7 @@
testDeregisterConfidentialClient(clientId);
}
+ @Deprecated
private void testRegisterClientNonUniqueURL () throws KustvaktException {
ClientResponse response = registerConfidentialClient();
assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
@@ -188,9 +189,9 @@
assertTrue(node.at("/client_secret").isMissingNode());
testResetPublicClientSecret(clientId);
- testAccessTokenAfterDeregistration(clientId, null);
+ testAccessTokenAfterDeregistration(clientId, null,null);
}
-
+
@Test
public void testRegisterDesktopApp () throws UniformInterfaceException,
ClientHandlerException, KustvaktException {
@@ -212,27 +213,73 @@
testDeregisterPublicClientMissingId();
testDeregisterPublicClient(clientId,username);
}
+
+ @Test
+ public void testRegisterMultipleDesktopApps () throws UniformInterfaceException,
+ ClientHandlerException, KustvaktException {
+
+ // First client
+ OAuth2ClientJson json = new OAuth2ClientJson();
+ json.setName("OAuth2DesktopClient1");
+ json.setType(OAuth2ClientType.PUBLIC);
+ json.setDescription("This is a desktop test client.");
+
+ ClientResponse response = registerClient(username, json);
+
+ String entity = response.getEntity(String.class);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ JsonNode node = JsonUtils.readTree(entity);
+ String clientId1 = node.at("/client_id").asText();
+ assertNotNull(clientId1);
+ assertTrue(node.at("/client_secret").isMissingNode());
+
+ // Second client
+ json = new OAuth2ClientJson();
+ json.setName("OAuth2DesktopClient2");
+ json.setType(OAuth2ClientType.PUBLIC);
+ json.setDescription("This is another desktop test client.");
+
+ response = registerClient(username, json);
+
+ entity = response.getEntity(String.class);
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ node = JsonUtils.readTree(entity);
+ String clientId2 = node.at("/client_id").asText();
+ assertNotNull(clientId2);
+ assertTrue(node.at("/client_secret").isMissingNode());
+
+ testResetPublicClientSecret(clientId1);
+ testAccessTokenAfterDeregistration(clientId1, null,
+ "https://OAuth2DesktopClient1.com");
+ testResetPublicClientSecret(clientId2);
+ testAccessTokenAfterDeregistration(clientId2, null,
+ "https://OAuth2DesktopClient2.com");
+ }
+
+
+
private void testAccessTokenAfterDeregistration (String clientId,
- String clientSecret) throws KustvaktException {
+ String clientSecret, String redirectUri) throws KustvaktException {
String userAuthHeader = HttpAuthorizationHandler
.createBasicAuthorizationHeaderValue("dory", "password");
- String code =
- requestAuthorizationCode(clientId, "", null, userAuthHeader);
+ String code = requestAuthorizationCode(clientId, "", null,
+ userAuthHeader, redirectUri);
ClientResponse response = requestTokenWithAuthorizationCodeAndForm(
- clientId, clientSecret, code);
+ clientId, clientSecret, code, redirectUri);
JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
String accessToken = node.at("/access_token").asText();
response = searchWithAccessToken(accessToken);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
- code = requestAuthorizationCode(clientId, "", null, userAuthHeader);
+ code = requestAuthorizationCode(clientId, "", null, userAuthHeader,
+ redirectUri);
testDeregisterPublicClient(clientId, username);
response = requestTokenWithAuthorizationCodeAndForm(clientId,
- clientSecret, code);
+ clientSecret, code, redirectUri);
assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
node = JsonUtils.readTree(response.getEntity(String.class));
assertEquals(OAuth2Error.INVALID_CLIENT.toString(),
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2TestBase.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2TestBase.java
index 91604bb..3d47f65 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2TestBase.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2TestBase.java
@@ -79,7 +79,32 @@
.fromUri(redirectUri).build().getQueryParams();
return params.getFirst("code");
}
+
+ protected String requestAuthorizationCode (String clientId,
+ String clientSecret, String scope, String authHeader,
+ String redirect_uri) throws KustvaktException {
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("response_type", "code");
+ form.add("client_id", clientId);
+ form.add("client_secret", clientSecret);
+ if (scope != null) {
+ form.add("scope", scope);
+ }
+ if (redirect_uri!=null){
+ form.add("redirect_uri", redirect_uri);
+ }
+
+ ClientResponse response = requestAuthorizationCode(form, authHeader);
+ assertEquals(Status.TEMPORARY_REDIRECT.getStatusCode(),
+ response.getStatus());
+ URI redirectUri = response.getLocation();
+
+ MultiValueMap<String, String> params = UriComponentsBuilder
+ .fromUri(redirectUri).build().getQueryParams();
+ return params.getFirst("code");
+ }
+
protected ClientResponse requestToken (MultivaluedMap<String, String> form)
throws KustvaktException {
return resource().path(API_VERSION).path("oauth2").path("token")
@@ -105,6 +130,25 @@
ContentType.APPLICATION_FORM_URLENCODED)
.entity(form).post(ClientResponse.class);
}
+
+ protected ClientResponse requestTokenWithAuthorizationCodeAndForm (
+ String clientId, String clientSecret, String code,
+ String redirectUri) throws KustvaktException {
+
+ MultivaluedMap<String, String> form = new MultivaluedMapImpl();
+ form.add("grant_type", "authorization_code");
+ form.add("client_id", clientId);
+ form.add("client_secret", clientSecret);
+ form.add("code", code);
+ if (redirectUri!=null){
+ form.add("redirect_uri", redirectUri);
+ }
+
+ return resource().path(API_VERSION).path("oauth2").path("token")
+ .header(HttpHeaders.CONTENT_TYPE,
+ ContentType.APPLICATION_FORM_URLENCODED)
+ .entity(form).post(ClientResponse.class);
+ }
// client credentials in authorization header
protected JsonNode requestTokenWithAuthorizationCodeAndHeader (String clientId,
diff --git a/full/src/test/resources/log4j2-test.properties b/full/src/test/resources/log4j2-test.properties
index dc7dc8f..c80f94c 100644
--- a/full/src/test/resources/log4j2-test.properties
+++ b/full/src/test/resources/log4j2-test.properties
@@ -1,8 +1,8 @@
-appenders = console
-appender.console.type = Console
-appender.console.name = STDOUT
-appender.console.layout.type = PatternLayout
-appender.console.layout.pattern = %d{yyyy-MM-dd, HH:mm:ss} %C{6} - %M%n %-5p: %m%n
+#appenders = console
+#appender.console.type = Console
+#appender.console.name = STDOUT
+#appender.console.layout.type = PatternLayout
+#appender.console.layout.pattern = %d{yyyy-MM-dd, HH:mm:ss} %C{6} - %M%n %-5p: %m%n
#appender.file.type = File
#appender.file.name = ERRORLOG
@@ -14,12 +14,12 @@
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT
-loggers=console
-logger.console.name=com.sun.jersey.test.framework.spi.container
-logger.console.level = info
-logger.console.appenderRefs = stdout
-logger.console.appenderRef.file.ref = STDOUT
-logger.console.additivity=false
+#loggers=console
+#logger.console.name=com.sun.jersey.test.framework.spi.container
+#logger.console.level = info
+#logger.console.appenderRefs = stdout
+#logger.console.appenderRef.file.ref = STDOUT
+#logger.console.additivity=false
#loggers=file
#logger.file.name=com.sun.jersey.test.framework.spi.container