mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 23:15:43 +01:00
Create DAO for repository roles
This commit is contained in:
225
scm-core/src/main/java/sonia/scm/repository/RepositoryRole.java
Normal file
225
scm-core/src/main/java/sonia/scm/repository/RepositoryRole.java
Normal file
@@ -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<String> verbs;
|
||||||
|
|
||||||
|
private Long creationDate;
|
||||||
|
private Long lastModified;
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor exists for mapstruct and JAXB, only -- <b>do not use this in "normal" code</b>.
|
||||||
|
*
|
||||||
|
* @deprecated Do not use this for "normal" code.
|
||||||
|
* Use {@link RepositoryRole#RepositoryRole(String, Collection, String)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public RepositoryRole() {}
|
||||||
|
|
||||||
|
public RepositoryRole(String name, Collection<String> 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<String> 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<String> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import sonia.scm.GenericDAO;
|
||||||
|
|
||||||
|
public interface RepositoryRoleDAO extends GenericDAO<RepositoryRole> {
|
||||||
|
}
|
||||||
@@ -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<RepositoryRole, XmlRepositoryRoleDatabase>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<RepositoryRole> {
|
||||||
|
|
||||||
|
private Long creationTime;
|
||||||
|
private Long lastModified;
|
||||||
|
|
||||||
|
@XmlJavaTypeAdapter(XmlRepositoryRoleMapAdapter.class)
|
||||||
|
@XmlElement(name = "roles")
|
||||||
|
private Map<String, RepositoryRole> roleMap = new LinkedHashMap<String, RepositoryRole>();
|
||||||
|
|
||||||
|
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<RepositoryRole> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<RepositoryRole> {
|
||||||
|
|
||||||
|
public XmlRepositoryRoleList() {}
|
||||||
|
|
||||||
|
public XmlRepositoryRoleList(Map<String, RepositoryRole> roleMap) {
|
||||||
|
this.roles = new LinkedList<RepositoryRole>(roleMap.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<RepositoryRole> iterator()
|
||||||
|
{
|
||||||
|
return roles.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedList<RepositoryRole> getRoles()
|
||||||
|
{
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(LinkedList<RepositoryRole> roles)
|
||||||
|
{
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@XmlElement(name = "role")
|
||||||
|
private LinkedList<RepositoryRole> roles;
|
||||||
|
}
|
||||||
@@ -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<XmlRepositoryRoleList, Map<String, RepositoryRole>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlRepositoryRoleList marshal(Map<String, RepositoryRole> roleMap) {
|
||||||
|
return new XmlRepositoryRoleList(roleMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, RepositoryRole> unmarshal(XmlRepositoryRoleList roles) {
|
||||||
|
Map<String, RepositoryRole> roleMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
for (RepositoryRole role : roles) {
|
||||||
|
roleMap.put(role.getName(), role);
|
||||||
|
}
|
||||||
|
|
||||||
|
return roleMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package sonia.scm.api.v2.resources;
|
|||||||
|
|
||||||
import de.otto.edison.hal.HalRepresentation;
|
import de.otto.edison.hal.HalRepresentation;
|
||||||
import de.otto.edison.hal.Links;
|
import de.otto.edison.hal.Links;
|
||||||
import sonia.scm.security.RepositoryRole;
|
import sonia.scm.repository.RepositoryRole;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package sonia.scm.api.v2.resources;
|
|||||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
import de.otto.edison.hal.Links;
|
import de.otto.edison.hal.Links;
|
||||||
import sonia.scm.security.RepositoryPermissionProvider;
|
import sonia.scm.security.SystemRepositoryPermissionProvider;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -19,11 +19,11 @@ public class RepositoryPermissionResource {
|
|||||||
|
|
||||||
static final String PATH = "v2/repositoryPermissions/";
|
static final String PATH = "v2/repositoryPermissions/";
|
||||||
|
|
||||||
private final RepositoryPermissionProvider repositoryPermissionProvider;
|
private final SystemRepositoryPermissionProvider repositoryPermissionProvider;
|
||||||
private final ResourceLinks resourceLinks;
|
private final ResourceLinks resourceLinks;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RepositoryPermissionResource(RepositoryPermissionProvider repositoryPermissionProvider, ResourceLinks resourceLinks) {
|
public RepositoryPermissionResource(SystemRepositoryPermissionProvider repositoryPermissionProvider, ResourceLinks resourceLinks) {
|
||||||
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<String> verbs;
|
|
||||||
|
|
||||||
public RepositoryRole(String name, Collection<String> verbs) {
|
|
||||||
this.name = name;
|
|
||||||
this.verbs = verbs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<String> 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ import com.google.inject.Inject;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import sonia.scm.plugin.PluginLoader;
|
import sonia.scm.plugin.PluginLoader;
|
||||||
|
import sonia.scm.repository.RepositoryRole;
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.JAXBException;
|
import javax.xml.bind.JAXBException;
|
||||||
@@ -23,19 +24,20 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.Collections.unmodifiableCollection;
|
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 static final String REPOSITORY_PERMISSION_DESCRIPTOR = "META-INF/scm/repository-permissions.xml";
|
||||||
private final Collection<String> availableVerbs;
|
private final Collection<String> availableVerbs;
|
||||||
private final Collection<RepositoryRole> availableRoles;
|
private final Collection<RepositoryRole> availableRoles;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RepositoryPermissionProvider(PluginLoader pluginLoader) {
|
public SystemRepositoryPermissionProvider(PluginLoader pluginLoader) {
|
||||||
AvailableRepositoryPermissions availablePermissions = readAvailablePermissions(pluginLoader);
|
AvailableRepositoryPermissions availablePermissions = readAvailablePermissions(pluginLoader);
|
||||||
this.availableVerbs = unmodifiableCollection(new LinkedHashSet<>(availablePermissions.availableVerbs));
|
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<String> availableVerbs() {
|
public Collection<String> availableVerbs() {
|
||||||
@@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import sonia.scm.plugin.PluginLoader;
|
import sonia.scm.plugin.PluginLoader;
|
||||||
import sonia.scm.repository.RepositoryPermissions;
|
import sonia.scm.repository.RepositoryPermissions;
|
||||||
|
import sonia.scm.repository.RepositoryRole;
|
||||||
import sonia.scm.util.ClassLoaders;
|
import sonia.scm.util.ClassLoaders;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
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.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
class RepositoryPermissionProviderTest {
|
class SystemRepositoryPermissionProviderTest {
|
||||||
|
|
||||||
private RepositoryPermissionProvider repositoryPermissionProvider;
|
private SystemRepositoryPermissionProvider repositoryPermissionProvider;
|
||||||
private String[] allVerbsFromRepositoryClass;
|
private String[] allVerbsFromRepositoryClass;
|
||||||
|
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ class RepositoryPermissionProviderTest {
|
|||||||
void init() {
|
void init() {
|
||||||
PluginLoader pluginLoader = mock(PluginLoader.class);
|
PluginLoader pluginLoader = mock(PluginLoader.class);
|
||||||
when(pluginLoader.getUberClassLoader()).thenReturn(ClassLoaders.getContextClassLoader(DefaultSecuritySystem.class));
|
when(pluginLoader.getUberClassLoader()).thenReturn(ClassLoaders.getContextClassLoader(DefaultSecuritySystem.class));
|
||||||
repositoryPermissionProvider = new RepositoryPermissionProvider(pluginLoader);
|
repositoryPermissionProvider = new SystemRepositoryPermissionProvider(pluginLoader);
|
||||||
allVerbsFromRepositoryClass = Arrays.stream(RepositoryPermissions.class.getDeclaredFields())
|
allVerbsFromRepositoryClass = Arrays.stream(RepositoryPermissions.class.getDeclaredFields())
|
||||||
.filter(field -> field.getName().startsWith("ACTION_"))
|
.filter(field -> field.getName().startsWith("ACTION_"))
|
||||||
.filter(field -> !field.getName().equals("ACTION_HEALTHCHECK"))
|
.filter(field -> !field.getName().equals("ACTION_HEALTHCHECK"))
|
||||||
Reference in New Issue
Block a user