diff --git a/scm-webapp/src/main/java/sonia/scm/security/ApiKeyService.java b/scm-webapp/src/main/java/sonia/scm/security/ApiKeyService.java index d666261cae..631c7aff3a 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/ApiKeyService.java +++ b/scm-webapp/src/main/java/sonia/scm/security/ApiKeyService.java @@ -33,6 +33,7 @@ import org.apache.shiro.util.ThreadContext; import sonia.scm.ContextEntry; import sonia.scm.store.DataStore; import sonia.scm.store.DataStoreFactory; +import sonia.scm.user.UserPermissions; import javax.inject.Inject; import java.security.SecureRandom; @@ -74,6 +75,7 @@ public class ApiKeyService { public CreationResult createNewKey(String name, String permissionRole) { String user = currentUser(); + UserPermissions.changeApiKeys(user).check(); String passphrase = passphraseGenerator.get(); String hashedPassphrase = passwordService.encryptPassword(passphrase); final String id = keyGenerator.createKey(); @@ -96,6 +98,7 @@ public class ApiKeyService { public void remove(String id) { String user = currentUser(); + UserPermissions.changeApiKeys(user).check(); Lock lock = locks.get(user).writeLock(); lock.lock(); try { diff --git a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java index ddc65a8c0d..b924769b6c 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java @@ -250,6 +250,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector builder.add(getUserAutocompletePermission()); builder.add(getGroupAutocompletePermission()); builder.add(getChangeOwnPasswordPermission(user)); + builder.add(getApiKeyPermission(user)); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(ImmutableSet.of(Role.USER)); @@ -266,6 +267,10 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector return UserPermissions.changePassword(user).asShiroString(); } + private String getApiKeyPermission(User user) { + return UserPermissions.changeApiKeys(user).asShiroString(); + } + private String getUserAutocompletePermission() { return UserPermissions.autocomplete().asShiroString(); } diff --git a/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java b/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java index 30a6e42d10..93cce78932 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java @@ -167,8 +167,8 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.contains(Role.USER)); - assertThat(authInfo.getStringPermissions(), hasSize(4)); - assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "user:read:trillian")); + assertThat(authInfo.getStringPermissions(), hasSize(5)); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "user:read:trillian", "user:changeApiKeys:trillian")); assertThat(authInfo.getObjectPermissions(), nullValue()); } @@ -212,7 +212,7 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); assertThat(authInfo.getObjectPermissions(), nullValue()); - assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian")); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian", "user:changeApiKeys:trillian")); } /** @@ -244,7 +244,7 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); assertThat(authInfo.getObjectPermissions(), nullValue()); - assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian")); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian", "user:changeApiKeys:trillian")); } /** @@ -287,7 +287,8 @@ public class DefaultAuthorizationCollectorTest { "repository:user:one", "repository:system:one", "repository:group:two", - "user:read:trillian")); + "user:read:trillian", + "user:changeApiKeys:trillian")); } /** @@ -334,7 +335,7 @@ public class DefaultAuthorizationCollectorTest { AuthorizationInfo authInfo = collector.collect(); assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); assertThat(authInfo.getObjectPermissions(), nullValue()); - assertThat(authInfo.getStringPermissions(), containsInAnyOrder("one:one", "two:two", "user:read:trillian", "user:autocomplete", "group:autocomplete", "user:changePassword:trillian")); + assertThat(authInfo.getStringPermissions(), containsInAnyOrder("one:one", "two:two", "user:read:trillian", "user:autocomplete", "group:autocomplete", "user:changePassword:trillian", "user:changeApiKeys:trillian")); } private void authenticate(User user, String group, String... groups) {