Merged in feature/consolidate_permissions (pull request #196)

Feature consolidate permissions
This commit is contained in:
Philipp Czora
2019-02-20 14:20:03 +00:00
26 changed files with 243 additions and 87 deletions

View File

@@ -826,7 +826,7 @@
<jetty.maven.version>9.4.14.v20181114</jetty.maven.version>
<!-- security libraries -->
<ssp.version>1.1.0</ssp.version>
<ssp.version>1.2.0</ssp.version>
<shiro.version>1.4.0</shiro.version>
<!-- repository libraries -->

View File

@@ -22,7 +22,8 @@ import com.github.sdorra.ssp.StaticPermissions;
@StaticPermissions(
value = "configuration",
permissions = {"read", "write"},
globalPermissions = {"list"}
globalPermissions = {"list"},
custom = true, customGlobal = true
)
public interface Configuration extends PermissionObject {
}

View File

@@ -61,7 +61,11 @@ import java.util.List;
*
* @author Sebastian Sdorra
*/
@StaticPermissions(value = "group", globalPermissions = {"create", "list", "autocomplete"})
@StaticPermissions(
value = "group",
globalPermissions = {"create", "list", "autocomplete"},
custom = true, customGlobal = true
)
@XmlRootElement(name = "groups")
@XmlAccessorType(XmlAccessType.FIELD)
public class Group extends BasicPropertiesAware

View File

@@ -61,7 +61,8 @@ import java.util.List;
value = "plugin",
generatedClass = "PluginPermissions",
permissions = {},
globalPermissions = { "read", "manage" }
globalPermissions = { "read", "manage" },
custom = true, customGlobal = true
)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "plugin-information")

View File

@@ -62,7 +62,8 @@ import java.util.Set;
*/
@StaticPermissions(
value = "repository",
permissions = {"read", "modify", "delete", "healthCheck", "pull", "push", "permissionRead", "permissionWrite"}
permissions = {"read", "modify", "delete", "healthCheck", "pull", "push", "permissionRead", "permissionWrite"},
custom = true, customGlobal = true
)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "repositories")

View File

@@ -6,7 +6,8 @@ import com.github.sdorra.ssp.StaticPermissions;
@StaticPermissions(
value = "permission",
permissions = {},
globalPermissions = {"list", "read", "assign"}
globalPermissions = {"list", "read", "assign"},
custom = true, customGlobal = true
)
public interface Permission extends PermissionObject {
}

View File

@@ -59,7 +59,9 @@ import java.security.Principal;
@StaticPermissions(
value = "user",
globalPermissions = {"create", "list", "autocomplete"},
permissions = {"read", "modify", "delete", "changePassword"})
permissions = {"read", "modify", "delete", "changePassword"},
custom = true, customGlobal = true
)
@XmlRootElement(name = "users")
@XmlAccessorType(XmlAccessType.FIELD)
public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject, ReducedModelObject

View File

@@ -34,10 +34,10 @@
<permissions>
<permission>
<value>configuration:read:git</value>
<value>configuration:read,write:git</value>
</permission>
<permission>
<value>configuration:write:git</value>
<value>repository:git:*</value>
</permission>
</permissions>

View File

@@ -0,0 +1,7 @@
<repository-permissions>
<verbs>
<verb>git</verb>
</verbs>
<roles>
</roles>
</repository-permissions>

View File

@@ -39,18 +39,28 @@
},
"permissions" : {
"configuration": {
"read": {
"read,write": {
"git": {
"displayName": "Git Konfiguration lesen",
"description": "Darf die git Konfiguration lesen."
}
},
"write": {
"git": {
"displayName": "Git Konfiguration schreiben",
"displayName": "Git Konfiguration ändern",
"description": "Darf die git Konfiguration verändern."
}
}
},
"repository": {
"git": {
"*": {
"displayName": "Repository-spezifische Git Konfiguration ändern",
"description": "Darf die git Konfiguration für alle Repositories verändern."
}
}
}
},
"verbs": {
"repository": {
"git": {
"displayName": "Git konfigurieren",
"description": "Darf die git Konfiguration für dieses Repository verändern."
}
}
}
}

View File

@@ -39,18 +39,28 @@
},
"permissions" : {
"configuration": {
"read": {
"read,write": {
"git": {
"displayName": "Read git configuration",
"description": "May read the git configuration"
}
},
"write": {
"git": {
"displayName": "Write git configuration",
"displayName": "Modify git configuration",
"description": "May change the git configuration"
}
}
},
"repository": {
"git": {
"*": {
"displayName": "Modify repository specific git configuration",
"description": "May change the git configuration for repositories"
}
}
}
},
"verbs": {
"repository": {
"git": {
"displayName": "configure Git",
"description": "May change the git configuration for this repository"
}
}
}
}

View File

@@ -34,10 +34,10 @@
<permissions>
<permission>
<value>configuration:read:hg</value>
<value>configuration:read,write:hg</value>
</permission>
<permission>
<value>configuration:write:hg</value>
<value>repository:hg:*</value>
</permission>
</permissions>

View File

@@ -0,0 +1,7 @@
<repository-permissions>
<verbs>
<verb>hg</verb>
</verbs>
<roles>
</roles>
</repository-permissions>

View File

@@ -31,18 +31,28 @@
},
"permissions" : {
"configuration": {
"read": {
"read,write": {
"hg": {
"displayName": "Mercurial Konfiguration lesen",
"description": "Darf die Mercurial Konfiguration lesen"
}
},
"write": {
"hg": {
"displayName": "Mercurial Konfiguration schreiben",
"displayName": "Mercurial Konfiguration ändern",
"description": "Darf die Mercurial Konfiguration verändern"
}
}
},
"repository": {
"hg": {
"*": {
"displayName": "Repository-spezifische Mercurial Konfiguration ändern",
"description": "Darf die Mercurial Konfiguration für alle Repositories verändern."
}
}
}
},
"verbs": {
"repository": {
"hg": {
"displayName": "Mercurial konfigurieren",
"description": "Darf die Mercurial Konfiguration für dieses Repository verändern."
}
}
}
}

View File

@@ -31,18 +31,28 @@
},
"permissions" : {
"configuration": {
"read": {
"read,write": {
"hg": {
"displayName": "Read Mercurial configuration",
"description": "May read the Mercurial configuration"
}
},
"write": {
"hg": {
"displayName": "Write Mercurial configuration",
"displayName": "Modify Mercurial configuration",
"description": "May change the Mercurial configuration"
}
}
},
"repository": {
"hg": {
"*": {
"displayName": "Modify repository specific Mercurial configuration",
"description": "May change the Mercurial configuration for repositories"
}
}
}
},
"verbs": {
"repository": {
"hg": {
"displayName": "configure Mercurial",
"description": "May change the Mercurial configuration for this repository"
}
}
}
}

View File

@@ -34,10 +34,10 @@
<permissions>
<permission>
<value>configuration:read:svn</value>
<value>configuration:read,write:svn</value>
</permission>
<permission>
<value>configuration:write:svn</value>
<value>repository:svn:*</value>
</permission>
</permissions>

View File

@@ -0,0 +1,7 @@
<repository-permissions>
<verbs>
<verb>svn</verb>
</verbs>
<roles>
</roles>
</repository-permissions>

View File

@@ -25,18 +25,28 @@
},
"permissions": {
"configuration": {
"read": {
"read,write": {
"svn": {
"displayName": "Subversion Konfiguration lesen",
"description": "Darf die Subversion Konfiguration lesen"
}
},
"write": {
"svn": {
"displayName": "Subversion Konfiguration schreiben",
"displayName": "Subversion Konfiguration ändern",
"description": "Darf die Subversion Konfiguration verändern"
}
}
},
"repository": {
"svn": {
"*": {
"displayName": "Repository-spezifische Subversion Konfiguration ändern",
"description": "Darf die Subversion Konfiguration für alle Repositories verändern."
}
}
}
},
"verbs": {
"repository": {
"svn": {
"displayName": "Subversion konfigurieren",
"description": "Darf die Subversion Konfiguration für dieses Repository verändern."
}
}
}
}

View File

@@ -25,18 +25,28 @@
},
"permissions": {
"configuration": {
"read": {
"read,write": {
"svn": {
"displayName": "Read Subversion configuration",
"description": "May read the Subversion configuration"
"displayName": "Modify Subversion configuration",
"description": "May modify the Subversion configuration"
}
},
"write": {
"svn": {
"displayName": "Write Subversion configuration",
"description": "May change the Subversion configuration"
}
},
"repository": {
"svn": {
"*": {
"displayName": "Modify repository specific Subversion configuration",
"description": "May change the Subversion configuration for repositories"
}
}
}
},
"verbs": {
"repository": {
"svn": {
"displayName": "configure Subversion",
"description": "May change the Subversion configuration for this repository"
}
}
}
}

View File

@@ -18,6 +18,7 @@ import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static java.util.Collections.unmodifiableCollection;
@@ -63,7 +64,7 @@ public class RepositoryPermissionProvider {
RepositoryPermissionsRoot repositoryPermissionsRoot = parsePermissionDescriptor(context, descriptorUrl);
availableVerbs.addAll(repositoryPermissionsRoot.verbs.verbs);
availableRoles.addAll(repositoryPermissionsRoot.roles.roles);
mergeRolesInto(availableRoles, repositoryPermissionsRoot.roles.roles);
}
} catch (IOException ex) {
logger.error("could not read permission descriptors", ex);
@@ -75,7 +76,22 @@ public class RepositoryPermissionProvider {
return new AvailableRepositoryPermissions(availableVerbs, availableRoles);
}
@SuppressWarnings("unchecked")
private static void mergeRolesInto(Collection<RoleDescriptor> targetRoles, List<RoleDescriptor> additionalRoles) {
additionalRoles.forEach(r -> addOrMergeInto(targetRoles, r));
}
private static void addOrMergeInto(Collection<RoleDescriptor> targetRoles, RoleDescriptor additionalRole) {
Optional<RoleDescriptor> existingRole = targetRoles
.stream()
.filter(r -> r.name.equals(additionalRole.name))
.findFirst();
if (existingRole.isPresent()) {
existingRole.get().verbs.verbs.addAll(additionalRole.verbs.verbs);
} else {
targetRoles.add(additionalRole);
}
}
private static RepositoryPermissionsRoot parsePermissionDescriptor(JAXBContext context, URL descriptorUrl) {
try {
RepositoryPermissionsRoot descriptorWrapper =

View File

@@ -40,7 +40,7 @@
<value>repository:read,pull,push:*</value>
</permission>
<permission>
<value>repository:*:*</value>
<value>repository:*</value>
</permission>
<permission>
<value>repository:create</value>
@@ -51,5 +51,14 @@
<permission>
<value>group:*</value>
</permission>
<permission>
<value>configuration:list</value>
</permission>
<permission>
<value>configuration:read,write:global</value>
</permission>
<permission>
<value>configuration:read,write:*</value>
</permission>
</permissions>

View File

@@ -7,7 +7,6 @@
<verb>push</verb>
<verb>permissionRead</verb>
<verb>permissionWrite</verb>
<verb>healthCheck</verb>
<verb>*</verb>
</verbs>
<roles>
@@ -26,12 +25,6 @@
<verb>push</verb>
</verbs>
</role>
<role>
<name>HEALTH</name>
<verbs>
<verb>healthCheck</verb>
</verbs>
</role>
<role>
<name>OWNER</name>
<verbs>

View File

@@ -14,10 +14,8 @@
}
},
"*": {
"*": {
"displayName": "Alle Repositories besitzen (Owner)",
"description": "Darf alle Repositories lesen, klonen, schreiben, konfigurieren und löschen."
}
"displayName": "Alle Repositories besitzen (Owner)",
"description": "Darf alle Repositories lesen, klonen, schreiben, konfigurieren und löschen."
},
"create": {
"displayName": "Repositories erstellen",
@@ -36,6 +34,22 @@
"description": "Darf Gruppen administrieren."
}
},
"configuration": {
"list": {
"displayName": "Basis für Administration",
"description": "Voraussetzung für alle anderen Administrationsberechtigungen. Ohne diese Berechtigung wird keine Administrationsansicht gezeigt."
},
"read,write": {
"global": {
"displayName": "zentrale Konfiguration",
"description": "Darf die Konfiguration des SCM-Manager anpassen"
},
"*": {
"displayName": "zentrale + Plugin Konfiguration",
"description": "Darf die Konfiguration des SCM-Manager und aller Plugins anpassen"
}
}
},
"unknown": "Unbekannte Berechtigung"
},
"verbs": {
@@ -68,10 +82,6 @@
"displayName": "Berechtigungen modifizieren",
"description": "Darf die Berechtigungen des Repository bearbeiten."
},
"healthCheck": {
"displayName": "Health Check",
"description": "Darf den Repository Health Check ausführen."
},
"*": {
"displayName": "Alle Repository Rechte",
"description": "Darf im Repository Kontext alles ausführen. Dies beinhaltet alle Repository Berechtigungen."

View File

@@ -14,10 +14,8 @@
}
},
"*": {
"*": {
"displayName": "Own all repositories",
"description": "May see, clone, push to, configure and delete all repositories"
}
"displayName": "Own all repositories",
"description": "May see, clone, push to, configure and delete all repositories"
},
"create": {
"displayName": "Create repositories",
@@ -36,6 +34,22 @@
"description": "May administer all groups"
}
},
"configuration": {
"list": {
"displayName": "Basic administration",
"description": "Prerequisite for all other administration permissions. Without this, no configuration will be visible."
},
"read,write": {
"global": {
"displayName": "Administer core",
"description": "May configure core settings of SCM-Manager"
},
"*": {
"displayName": "Administer core and plugins",
"description": "May configure settings of SCM-Manager core and all plugins"
}
}
},
"unknown": "Unknown permission"
},
"verbs": {
@@ -68,10 +82,6 @@
"displayName": "modify permissions",
"description": "May modify the permissions of the repository"
},
"healthCheck": {
"displayName": "health check",
"description": "May run the health check for the repository"
},
"*": {
"displayName": "overall",
"description": "May change everything for the repository (includes all other permissions)"

View File

@@ -8,6 +8,7 @@ import sonia.scm.util.ClassLoaders;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
@@ -27,6 +28,7 @@ class RepositoryPermissionProviderTest {
repositoryPermissionProvider = new RepositoryPermissionProvider(pluginLoader);
allVerbsFromRepositoryClass = Arrays.stream(RepositoryPermissions.class.getDeclaredFields())
.filter(field -> field.getName().startsWith("ACTION_"))
.filter(field -> !field.getName().equals("ACTION_HEALTHCHECK"))
.map(this::getString)
.filter(verb -> !"create".equals(verb))
.toArray(String[]::new);
@@ -47,6 +49,18 @@ class RepositoryPermissionProviderTest {
assertThat(repositoryPermissionProvider.availableVerbs()).contains(allVerbsFromRepositoryClass);
}
@Test
void shouldMergeRepositoryRoles() {
Collection<String> verbsInMergedRole = repositoryPermissionProvider
.availableRoles()
.stream()
.filter(r -> "READ".equals(r.getName()))
.findFirst()
.get()
.getVerbs();
assertThat(verbsInMergedRole).contains("read", "pull", "test");
}
private String getString(Field field) {
try {
return (String) field.get(null);

View File

@@ -0,0 +1,13 @@
<repository-permissions>
<verbs>
<verb>test</verb>
</verbs>
<roles>
<role>
<name>READ</name>
<verbs>
<verb>test</verb>
</verbs>
</role>
</roles>
</repository-permissions>