From 232102716c982b6cff90e515ac05aed46d6c044c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 3 May 2019 14:19:33 +0200 Subject: [PATCH] Create DAO for repository roles --- .../sonia/scm/repository/RepositoryRole.java | 225 ++++++++++++++++++ .../scm/repository/RepositoryRoleDAO.java | 6 + .../repository/xml/XmlRepositoryRoleDAO.java | 33 +++ .../xml/XmlRepositoryRoleDatabase.java | 77 ++++++ .../repository/xml/XmlRepositoryRoleList.java | 74 ++++++ .../xml/XmlRepositoryRoleMapAdapter.java | 60 +++++ .../AvailableRepositoryPermissionsDto.java | 2 +- .../RepositoryPermissionResource.java | 6 +- .../sonia/scm/security/RepositoryRole.java | 43 ---- ...> SystemRepositoryPermissionProvider.java} | 10 +- ...stemRepositoryPermissionProviderTest.java} | 7 +- 11 files changed, 489 insertions(+), 54 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryRole.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryRoleDAO.java create mode 100644 scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDAO.java create mode 100644 scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDatabase.java create mode 100644 scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleList.java create mode 100644 scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleMapAdapter.java delete mode 100644 scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java rename scm-webapp/src/main/java/sonia/scm/security/{RepositoryPermissionProvider.java => SystemRepositoryPermissionProvider.java} (90%) rename scm-webapp/src/test/java/sonia/scm/security/{RepositoryPermissionProviderTest.java => SystemRepositoryPermissionProviderTest.java} (89%) diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryRole.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryRole.java new file mode 100644 index 0000000000..ca77f255f8 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryRole.java @@ -0,0 +1,225 @@ +/* + Copyright (c) 2010, Sebastian Sdorra + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of SCM-Manager; nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + http://bitbucket.org/sdorra/scm-manager + + */ + + + +package sonia.scm.repository; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Objects; +import com.google.common.base.Strings; +import sonia.scm.ModelObject; +import sonia.scm.user.User; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; + +import static java.util.Collections.emptyList; +import static java.util.Collections.emptySet; +import static java.util.Collections.unmodifiableSet; + +/** + * Custom role with specific permissions related to {@link Repository}. + * This object should be immutable, but could not be due to mapstruct. + */ +@XmlRootElement(name = "roles") +@XmlAccessorType(XmlAccessType.FIELD) +public class RepositoryRole implements ModelObject { + + private static final long serialVersionUID = -723588336073192740L; + + private static final String REPOSITORY_MODIFIED_EXCEPTION_TEXT = "roles must not be modified"; + + private String name; + @XmlElement(name = "verb") + private Set verbs; + + private Long creationDate; + private Long lastModified; + private String type; + + /** + * This constructor exists for mapstruct and JAXB, only -- do not use this in "normal" code. + * + * @deprecated Do not use this for "normal" code. + * Use {@link RepositoryRole#RepositoryRole(String, Collection, String)} instead. + */ + @Deprecated + public RepositoryRole() {} + + public RepositoryRole(String name, Collection verbs, String type) { + this.name = name; + this.verbs = new LinkedHashSet<>(verbs); + this.type = type; + } + + /** + * Returns true if the {@link RepositoryRole} is the same as the obj argument. + * + * + * @param obj the reference object with which to compare + * + * @return true if the {@link RepositoryRole} is the same as the obj argument + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + final RepositoryRole other = (RepositoryRole) obj; + + return Objects.equal(name, other.name) + && verbs.size() == other.verbs.size() + && verbs.containsAll(other.verbs); + } + + /** + * Returns the hash code value for the {@link RepositoryRole}. + * + * + * @return the hash code value for the {@link RepositoryRole} + */ + @Override + public int hashCode() { + return Objects.hashCode(name, verbs); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name) + .add("verbs", verbs) + .toString(); + } + + public String getName() { + return name; + } + + /** + * Returns the verb of the role. + */ + public Collection getVerbs() { + return verbs == null ? emptyList() : Collections.unmodifiableSet(verbs); + } + + @Override + public String getId() { + return name; + } + + @Override + public void setLastModified(Long timestamp) { + this.lastModified = timestamp; + } + + @Override + public Long getCreationDate() { + return creationDate; + } + + @Override + public void setCreationDate(Long timestamp) { + this.creationDate = timestamp; + } + + @Override + public Long getLastModified() { + return lastModified; + } + + @Override + public String getType() { + return type; + } + + public void setType(String type) { + if (this.type != null) { + throw new IllegalStateException(REPOSITORY_MODIFIED_EXCEPTION_TEXT); + } + this.type = type; + } + + @Override + public boolean isValid() { + return !Strings.isNullOrEmpty(name) && !verbs.isEmpty(); + } + + /** + * Use this for creation only. This will throw an {@link IllegalStateException} when modified. + * @throws IllegalStateException when modified after the value has been set once. + * + * @deprecated Do not use this for "normal" code. + * Use {@link RepositoryRole#RepositoryRole(String, Collection, String)} instead. + */ + @Deprecated + public void setName(String name) { + if (this.name != null) { + throw new IllegalStateException(REPOSITORY_MODIFIED_EXCEPTION_TEXT); + } + this.name = name; + } + + /** + * Use this for creation only. This will throw an {@link IllegalStateException} when modified. + * @throws IllegalStateException when modified after the value has been set once. + * + * @deprecated Do not use this for "normal" code. + * Use {@link RepositoryRole#RepositoryRole(String, Collection, String)} instead. + */ + @Deprecated + public void setVerbs(Collection verbs) { + if (this.verbs != null) { + throw new IllegalStateException(REPOSITORY_MODIFIED_EXCEPTION_TEXT); + } + this.verbs = verbs == null? emptySet(): unmodifiableSet(new LinkedHashSet<>(verbs)); + } + + @Override + public RepositoryRole clone() { + try { + return (RepositoryRole) super.clone(); + } catch (CloneNotSupportedException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryRoleDAO.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryRoleDAO.java new file mode 100644 index 0000000000..82bd163989 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryRoleDAO.java @@ -0,0 +1,6 @@ +package sonia.scm.repository; + +import sonia.scm.GenericDAO; + +public interface RepositoryRoleDAO extends GenericDAO { +} diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDAO.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDAO.java new file mode 100644 index 0000000000..4fa814e3c8 --- /dev/null +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDAO.java @@ -0,0 +1,33 @@ +package sonia.scm.repository.xml; + +import com.google.inject.Inject; +import sonia.scm.repository.RepositoryRole; +import sonia.scm.repository.RepositoryRoleDAO; +import sonia.scm.store.ConfigurationStoreFactory; +import sonia.scm.xml.AbstractXmlDAO; + +public class XmlRepositoryRoleDAO extends AbstractXmlDAO + implements RepositoryRoleDAO { + + public static final String STORE_NAME = "repositoryRoles"; + + @Inject + public XmlRepositoryRoleDAO(ConfigurationStoreFactory storeFactory) { + super(storeFactory + .withType(XmlRepositoryRoleDatabase.class) + .withName(STORE_NAME) + .build()); + } + + @Override + protected RepositoryRole clone(RepositoryRole role) + { + return role.clone(); + } + + @Override + protected XmlRepositoryRoleDatabase createNewDatabase() + { + return new XmlRepositoryRoleDatabase(); + } +} diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDatabase.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDatabase.java new file mode 100644 index 0000000000..8219d32a67 --- /dev/null +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleDatabase.java @@ -0,0 +1,77 @@ +package sonia.scm.repository.xml; + +import sonia.scm.repository.RepositoryRole; +import sonia.scm.xml.XmlDatabase; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +@XmlRootElement(name = "user-db") +@XmlAccessorType(XmlAccessType.FIELD) +public class XmlRepositoryRoleDatabase implements XmlDatabase { + + private Long creationTime; + private Long lastModified; + + @XmlJavaTypeAdapter(XmlRepositoryRoleMapAdapter.class) + @XmlElement(name = "roles") + private Map roleMap = new LinkedHashMap(); + + public XmlRepositoryRoleDatabase() { + long c = System.currentTimeMillis(); + + creationTime = c; + lastModified = c; + } + + @Override + public void add(RepositoryRole role) { + roleMap.put(role.getName(), role); + } + + @Override + public boolean contains(String name) { + return roleMap.containsKey(name); + } + + @Override + public RepositoryRole remove(String name) { + return roleMap.remove(name); + } + + @Override + public Collection values() { + return roleMap.values(); + } + + @Override + public RepositoryRole get(String name) { + return roleMap.get(name); + } + + @Override + public long getCreationTime() { + return creationTime; + } + + @Override + public long getLastModified() { + return lastModified; + } + + @Override + public void setCreationTime(long creationTime) { + this.creationTime = creationTime; + } + + @Override + public void setLastModified(long lastModified) { + this.lastModified = lastModified; + } +} diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleList.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleList.java new file mode 100644 index 0000000000..7910d4300a --- /dev/null +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleList.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository.xml; + +import sonia.scm.repository.RepositoryRole; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +@XmlRootElement(name = "roles") +@XmlAccessorType(XmlAccessType.FIELD) +public class XmlRepositoryRoleList implements Iterable { + + public XmlRepositoryRoleList() {} + + public XmlRepositoryRoleList(Map roleMap) { + this.roles = new LinkedList(roleMap.values()); + } + + @Override + public Iterator iterator() + { + return roles.iterator(); + } + + public LinkedList getRoles() + { + return roles; + } + + public void setRoles(LinkedList roles) + { + this.roles = roles; + } + + @XmlElement(name = "role") + private LinkedList roles; +} diff --git a/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleMapAdapter.java b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleMapAdapter.java new file mode 100644 index 0000000000..959eff331a --- /dev/null +++ b/scm-dao-xml/src/main/java/sonia/scm/repository/xml/XmlRepositoryRoleMapAdapter.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository.xml; + +import sonia.scm.repository.RepositoryRole; + +import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.util.LinkedHashMap; +import java.util.Map; + +public class XmlRepositoryRoleMapAdapter + extends XmlAdapter> { + + @Override + public XmlRepositoryRoleList marshal(Map roleMap) { + return new XmlRepositoryRoleList(roleMap); + } + + @Override + public Map unmarshal(XmlRepositoryRoleList roles) { + Map roleMap = new LinkedHashMap<>(); + + for (RepositoryRole role : roles) { + roleMap.put(role.getName(), role); + } + + return roleMap; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AvailableRepositoryPermissionsDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AvailableRepositoryPermissionsDto.java index 60203b565b..681be90a38 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AvailableRepositoryPermissionsDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/AvailableRepositoryPermissionsDto.java @@ -2,7 +2,7 @@ package sonia.scm.api.v2.resources; import de.otto.edison.hal.HalRepresentation; import de.otto.edison.hal.Links; -import sonia.scm.security.RepositoryRole; +import sonia.scm.repository.RepositoryRole; import java.util.Collection; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionResource.java index e5734085ca..df042f3e61 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionResource.java @@ -3,7 +3,7 @@ package sonia.scm.api.v2.resources; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import de.otto.edison.hal.Links; -import sonia.scm.security.RepositoryPermissionProvider; +import sonia.scm.security.SystemRepositoryPermissionProvider; import sonia.scm.web.VndMediaType; import javax.inject.Inject; @@ -19,11 +19,11 @@ public class RepositoryPermissionResource { static final String PATH = "v2/repositoryPermissions/"; - private final RepositoryPermissionProvider repositoryPermissionProvider; + private final SystemRepositoryPermissionProvider repositoryPermissionProvider; private final ResourceLinks resourceLinks; @Inject - public RepositoryPermissionResource(RepositoryPermissionProvider repositoryPermissionProvider, ResourceLinks resourceLinks) { + public RepositoryPermissionResource(SystemRepositoryPermissionProvider repositoryPermissionProvider, ResourceLinks resourceLinks) { this.repositoryPermissionProvider = repositoryPermissionProvider; this.resourceLinks = resourceLinks; } diff --git a/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java b/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java deleted file mode 100644 index 1fab500d79..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/security/RepositoryRole.java +++ /dev/null @@ -1,43 +0,0 @@ -package sonia.scm.security; - -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; - -public class RepositoryRole { - - private final String name; - private final Collection verbs; - - public RepositoryRole(String name, Collection verbs) { - this.name = name; - this.verbs = verbs; - } - - public String getName() { - return name; - } - - public Collection getVerbs() { - return Collections.unmodifiableCollection(verbs); - } - - public String toString() { - return "Role " + name + " (" + String.join(", ", verbs) + ")"; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof RepositoryRole)) return false; - RepositoryRole that = (RepositoryRole) o; - return name.equals(that.name) - && this.verbs.containsAll(that.verbs) - && this.verbs.size() == that.verbs.size(); - } - - @Override - public int hashCode() { - return Objects.hash(name, verbs.size()); - } -} diff --git a/scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionProvider.java b/scm-webapp/src/main/java/sonia/scm/security/SystemRepositoryPermissionProvider.java similarity index 90% rename from scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionProvider.java rename to scm-webapp/src/main/java/sonia/scm/security/SystemRepositoryPermissionProvider.java index 070990c6d6..5856abbc8b 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionProvider.java +++ b/scm-webapp/src/main/java/sonia/scm/security/SystemRepositoryPermissionProvider.java @@ -4,6 +4,7 @@ import com.google.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.plugin.PluginLoader; +import sonia.scm.repository.RepositoryRole; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; @@ -23,19 +24,20 @@ import java.util.Set; import java.util.stream.Collectors; import static java.util.Collections.unmodifiableCollection; +import static java.util.Collections.unmodifiableList; -public class RepositoryPermissionProvider { +public class SystemRepositoryPermissionProvider { - private static final Logger logger = LoggerFactory.getLogger(RepositoryPermissionProvider.class); + private static final Logger logger = LoggerFactory.getLogger(SystemRepositoryPermissionProvider.class); private static final String REPOSITORY_PERMISSION_DESCRIPTOR = "META-INF/scm/repository-permissions.xml"; private final Collection availableVerbs; private final Collection availableRoles; @Inject - public RepositoryPermissionProvider(PluginLoader pluginLoader) { + public SystemRepositoryPermissionProvider(PluginLoader pluginLoader) { AvailableRepositoryPermissions availablePermissions = readAvailablePermissions(pluginLoader); this.availableVerbs = unmodifiableCollection(new LinkedHashSet<>(availablePermissions.availableVerbs)); - this.availableRoles = unmodifiableCollection(new LinkedHashSet<>(availablePermissions.availableRoles.stream().map(r -> new RepositoryRole(r.name, r.verbs.verbs)).collect(Collectors.toList()))); + this.availableRoles = unmodifiableList(new LinkedHashSet<>(availablePermissions.availableRoles.stream().map(r -> new RepositoryRole(r.name, r.verbs.verbs, "system")).collect(Collectors.toList()))); } public Collection availableVerbs() { diff --git a/scm-webapp/src/test/java/sonia/scm/security/RepositoryPermissionProviderTest.java b/scm-webapp/src/test/java/sonia/scm/security/SystemRepositoryPermissionProviderTest.java similarity index 89% rename from scm-webapp/src/test/java/sonia/scm/security/RepositoryPermissionProviderTest.java rename to scm-webapp/src/test/java/sonia/scm/security/SystemRepositoryPermissionProviderTest.java index 8a8d85fdb2..8d1685b926 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/RepositoryPermissionProviderTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/SystemRepositoryPermissionProviderTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import sonia.scm.plugin.PluginLoader; import sonia.scm.repository.RepositoryPermissions; +import sonia.scm.repository.RepositoryRole; import sonia.scm.util.ClassLoaders; import java.lang.reflect.Field; @@ -15,9 +16,9 @@ import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -class RepositoryPermissionProviderTest { +class SystemRepositoryPermissionProviderTest { - private RepositoryPermissionProvider repositoryPermissionProvider; + private SystemRepositoryPermissionProvider repositoryPermissionProvider; private String[] allVerbsFromRepositoryClass; @@ -25,7 +26,7 @@ class RepositoryPermissionProviderTest { void init() { PluginLoader pluginLoader = mock(PluginLoader.class); when(pluginLoader.getUberClassLoader()).thenReturn(ClassLoaders.getContextClassLoader(DefaultSecuritySystem.class)); - repositoryPermissionProvider = new RepositoryPermissionProvider(pluginLoader); + repositoryPermissionProvider = new SystemRepositoryPermissionProvider(pluginLoader); allVerbsFromRepositoryClass = Arrays.stream(RepositoryPermissions.class.getDeclaredFields()) .filter(field -> field.getName().startsWith("ACTION_")) .filter(field -> !field.getName().equals("ACTION_HEALTHCHECK"))