You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2020/11/26 21:20:31 UTC
[archiva-redback-core] 01/05: Refactoring of role API and new Role
V2 REST service
This is an automated email from the ASF dual-hosted git repository.
martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva-redback-core.git
commit de23f72bf11a46ab0dd3b5f67d82d4101b20b897
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Tue Nov 24 21:28:42 2020 +0100
Refactoring of role API and new Role V2 REST service
---
README.adoc | 11 +
.../redback/common/ldap/role/LdapRoleMapper.java | 1 -
.../apache/archiva/redback/rest/api/Constants.java | 2 +-
.../archiva/redback/rest/api/MessageKeys.java | 13 +-
.../redback/rest/api/model/v2/Application.java | 89 ++++
.../redback/rest/api/model/v2/BaseGroupInfo.java | 80 ++++
.../redback/rest/api/model/v2/BaseRoleInfo.java | 262 +++++++++++
.../redback/rest/api/model/v2/BaseUserInfo.java | 67 +++
.../archiva/redback/rest/api/model/v2/Role.java | 104 +++++
.../redback/rest/api/model/v2/RoleInfo.java | 182 ++++++++
.../redback/rest/api/model/v2/RoleTree.java | 74 +++
.../redback/rest/api/model/v2/UserInfo.java | 36 +-
.../redback/rest/api/services/v2/RoleService.java | 444 ++++++++++--------
.../redback/rest/api/services/v2/UserService.java | 61 ++-
.../services/DefaultRoleManagementService.java | 5 +-
.../rest/services/v2/BaseRedbackService.java | 145 ++++++
.../rest/services/v2/DefaultGroupService.java | 8 +-
.../rest/services/v2/DefaultRoleService.java | 434 ++++++++++++++++++
.../rest/services/v2/DefaultUserService.java | 185 +++++---
.../redback/rest/services/v2/QueryHelper.java | 168 +++++++
.../src/main/resources/META-INF/spring-context.xml | 2 +-
.../services/v2/AbstractNativeRestServices.java | 2 +-
.../rest/services/v2/NativeRoleServiceTest.java | 505 +++++++++++++++++++++
.../rest/services/v2/NativeUserServiceTest.java | 132 +++++-
.../archiva/redback/rbac/AbstractRBACManager.java | 83 +++-
.../apache/archiva/redback/rbac/AbstractRole.java | 9 +-
.../apache/archiva/redback/rbac/RBACManager.java | 26 +-
.../java/org/apache/archiva/redback/rbac/Role.java | 26 ++
.../redback/rbac/cached/CachedRbacManager.java | 22 +-
.../archiva/redback/rbac/jpa/JpaRbacManager.java | 18 +-
.../archiva/redback/rbac/jpa/model/JpaRole.java | 44 +-
.../archiva/redback/rbac/jpa/model/RoleId.java | 40 +-
.../archiva/redback/rbac/ldap/LdapRbacManager.java | 45 +-
.../archiva/redback/rbac/memory/MemoryRole.java | 22 +
.../archiva/redback/role/DefaultRoleManager.java | 23 +-
.../archiva/redback/role/RoleExistsException.java | 16 +-
.../apache/archiva/redback/role/RoleManager.java | 4 +-
.../redback/role/RoleNotFoundException.java | 16 +-
.../role/processor/DefaultRoleModelProcessor.java | 3 +-
.../template/DefaultRoleTemplateProcessor.java | 40 +-
.../role/template/RoleTemplateProcessor.java | 26 +-
.../AbstractRbacManagerPerformanceTestCase.java | 2 +
.../redback/tests/AbstractRbacManagerTestCase.java | 6 +-
.../archiva/redback/tests/utils/RBACDefaults.java | 3 +
44 files changed, 3097 insertions(+), 389 deletions(-)
diff --git a/README.adoc b/README.adoc
index 568868b..646c17a 100644
--- a/README.adoc
+++ b/README.adoc
@@ -2,6 +2,17 @@ Archiva Redback - Documentation
===============================
:toc:
+== Update Information for 3.0
+
+=== Database Schema Changes
+
+==== org.apache.archiva.redback.rbac.Role
+
+New fields:
+id, modelId, isTemplateInstance, resource
+
+Primary key changed from name to combined key id,name
+
== How to build and publish the pages for the archiva web content
diff --git a/redback-common/redback-common-ldap/src/main/java/org/apache/archiva/redback/common/ldap/role/LdapRoleMapper.java b/redback-common/redback-common-ldap/src/main/java/org/apache/archiva/redback/common/ldap/role/LdapRoleMapper.java
index 1ee2cfe..43bea95 100644
--- a/redback-common/redback-common-ldap/src/main/java/org/apache/archiva/redback/common/ldap/role/LdapRoleMapper.java
+++ b/redback-common/redback-common-ldap/src/main/java/org/apache/archiva/redback/common/ldap/role/LdapRoleMapper.java
@@ -66,7 +66,6 @@ public interface LdapRoleMapper
boolean hasRole( DirContext context, String role )
throws MappingException;
-
/**
* @return the base dn which contains all ldap groups
*/
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
index 3faaf8c..f70ad58 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
@@ -23,7 +23,7 @@ package org.apache.archiva.redback.rest.api;
*/
public interface Constants
{
- String DEFAULT_PAGE_LIMIT = "1000";
+ String DEFAULT_PAGE_LIMIT = "100";
}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/MessageKeys.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/MessageKeys.java
index 6f7219a..51f762d 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/MessageKeys.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/MessageKeys.java
@@ -40,10 +40,19 @@ public interface MessageKeys
String ERR_USER_ADMIN_EXISTS = "rb.user.admin.exists";
String ERR_USER_ADMIN_BAD_NAME = "rb.user.admin.badname";
String ERR_USER_NOT_FOUND = "rb.user.not_found";
+ String ERR_USER_BAD_PASSWORD = "rb.user.bad.password";
String ERR_PASSWORD_VIOLATION = "rb.user.password_violation";
+
String ERR_LDAP_GENERIC = "rb.ldap.error";
String ERR_ROLE_MAPPING = "rb.role.mapping.error";
String ERR_ROLE_MAPPING_NOT_FOUND = "rb.role.mapping.not_found";
+ String ERR_ROLE_NOT_FOUND = "rb.role.not_found";
+ // A template instance not found. With arguments templateId, resource
+ String ERR_ROLE_INSTANCE_NOT_FOUND = "rb.role.instance.not_found";
+ String ERR_ROLE_EXISTS = "rb.role.exists";
+ // A template instance exists. With arguments templateId, resource
+ String ERR_ROLE_INSTANCE_EXISTS = "rb.role.instance.exists";
+
String ERR_AUTH_BAD_CODE = "rb.auth.bad_authorization_code";
String ERR_AUTH_INVALID_CREDENTIALS = "rb.auth.invalid_credentials";
String ERR_AUTH_FAIL_MSG = "rb.auth.fail";
@@ -52,9 +61,11 @@ public interface MessageKeys
String ERR_AUTH_UNSUPPORTED_GRANT_TYPE = "rb.auth.unsupported_grant";
String ERR_AUTH_INVALID_TOKEN = "rb.auth.invalid_token";
String ERR_AUTH_UNAUTHORIZED_REQUEST = "rb.auth.unauthorized_request";
+
String ERR_PASSWD_RESET_FAILED = "rb.passwd.reset.fail";
- String ERR_USER_BAD_PASSWORD = "rb.user.bad.password";
+
String ERR_REGISTRATION_KEY_INVALID = "rb.registration.key.invalid";
String ERR_REGISTRATION_USER_VALIDATED = "rb.registration.user.validated";
String ERR_REGISTRATION_ROLE_ASSIGNMENT_FAILED = "rb.registration.role.assignment.failed";
+
}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/Application.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/Application.java
new file mode 100644
index 0000000..c38392c
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/Application.java
@@ -0,0 +1,89 @@
+package org.apache.archiva.redback.rest.api.model.v2;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+/**
+ * @author Olivier Lamy
+ */
+@XmlRootElement( name = "application" )
+@Schema(name="Application", description = "A single application that is used for defining roles")
+public class Application
+ implements Serializable
+{
+ private static final long serialVersionUID = -4738856943947960583L;
+
+ private String version;
+ private String id;
+ private String description;
+ private String longDescription;
+
+ public Application()
+ {
+ // no op
+ }
+
+ @Schema(description = "The application version. Used to separate different sets of roles.")
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ @Schema(description = "The identifier of the application")
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema(description = "A short description.")
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ @Schema(description = "May be a longer explanation, of the application purpose and its defined roles.")
+ public String getLongDescription()
+ {
+ return longDescription;
+ }
+
+ public void setLongDescription( String longDescription )
+ {
+ this.longDescription = longDescription;
+ }
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseGroupInfo.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseGroupInfo.java
new file mode 100644
index 0000000..22ff830
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseGroupInfo.java
@@ -0,0 +1,80 @@
+package org.apache.archiva.redback.rest.api.model.v2;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+
+/**
+ * Information about a group.
+ *
+ * @since 3.0
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+@Schema( name = "Group", description = "Group information" )
+public class BaseGroupInfo implements Serializable
+{
+ private static final long serialVersionUID = 2945927911204165322L;
+ private String id;
+ private String groupName;
+ private String description = "";
+
+ public BaseGroupInfo( )
+ {
+
+ }
+
+ public BaseGroupInfo( String id, String groupName )
+ {
+ this.id = id;
+ this.groupName = groupName;
+ }
+
+ @Schema(description = "The name of the group")
+ public String getGroupName( )
+ {
+ return groupName;
+ }
+
+ public void setGroupName( String groupName )
+ {
+ this.groupName = groupName;
+ }
+
+ @Schema( description = "The unique identifier of the group" )
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema( description = "A description of the group" )
+ public String getDescription( )
+ {
+ return description;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseRoleInfo.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseRoleInfo.java
new file mode 100644
index 0000000..126a5e0
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseRoleInfo.java
@@ -0,0 +1,262 @@
+package org.apache.archiva.redback.rest.api.model.v2;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.redback.rbac.Role;
+import org.apache.archiva.redback.role.model.ModelRole;
+
+import javax.xml.bind.annotation.XmlTransient;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Basic role information. This class contains only the standard attributes used for displaying a role.
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+@Schema(name="BaseRoleInfo", description = "Basic role attributes")
+public class BaseRoleInfo implements Serializable
+{
+ private static final long serialVersionUID = -6725489773301720068L;
+
+ protected String id;
+ protected String name;
+ protected String description = "";
+ protected boolean permanent = false;
+ protected String modelId = "";
+ protected String resource = "";
+ protected boolean isTemplateInstance = false;
+ protected boolean assignable = true;
+ private String applicationId = "";
+ private boolean isChild = false;
+
+ protected boolean assigned = false;
+ private List<BaseRoleInfo> children = new ArrayList<>( 0 );
+
+ public BaseRoleInfo() {
+
+ }
+
+ public static BaseRoleInfo ofName(String name) {
+ BaseRoleInfo info = new BaseRoleInfo( );
+ info.setName( name );
+ return info;
+ }
+
+ public static BaseRoleInfo ofId(String id) {
+ BaseRoleInfo info = new BaseRoleInfo( );
+ info.setId( id );
+ return info;
+ }
+
+ public static BaseRoleInfo of(Role rbacRole) {
+ return of( rbacRole, new BaseRoleInfo( ) );
+ }
+
+
+ public static <T extends BaseRoleInfo> T of( Role rbacRole, T role ) {
+ role.id = rbacRole.getId( );
+ role.name = rbacRole.getName( );
+ role.description = rbacRole.getDescription( ) == null ?"": rbacRole.getDescription();
+ role.permanent = rbacRole.isPermanent( );
+ role.modelId = rbacRole.getModelId( );
+ role.resource = rbacRole.getResource( );
+ role.isTemplateInstance = rbacRole.isTemplateInstance( );
+ role.assignable = rbacRole.isAssignable( );
+ return role;
+ }
+
+
+
+ @Schema(description = "The role name")
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ @Schema( description = "A description of the role" )
+ public String getDescription( )
+ {
+ return description;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ @Schema( description = "True, if this role cannot be deleted.")
+ public boolean isPermanent()
+ {
+ return permanent;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ this.permanent = permanent;
+ }
+
+ @Schema(description = "The identifier of this role")
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema(description = "The model this role is derived from")
+ public String getModelId( )
+ {
+ return modelId;
+ }
+
+ public void setModelId( String modelId )
+ {
+ this.modelId = modelId;
+ }
+
+ @Schema(description = "The resource this model is built for, if it is built by a template.")
+ public String getResource( )
+ {
+ return resource;
+ }
+
+ public void setResource( String resource )
+ {
+ this.resource = resource;
+ }
+
+ @Schema(description = "True, if this is a instance of a role template")
+ public boolean isTemplateInstance( )
+ {
+ return isTemplateInstance;
+ }
+
+ public void setTemplateInstance( boolean templateInstance )
+ {
+ isTemplateInstance = templateInstance;
+ }
+
+ @Schema(description = "Roles that are children of this role. This field may not be populated, depending on the REST method call.")
+ public List<BaseRoleInfo> getChildren( )
+ {
+ return children;
+ }
+
+ public void setChildren( List<BaseRoleInfo> children )
+ {
+ this.children = children;
+ }
+
+ public void addChild(BaseRoleInfo child) {
+ if (!this.children.contains( child ))
+ {
+ this.children.add( child );
+ }
+ }
+
+ @Schema(description = "This attribute is only set at specific REST calls, that return roles, that are either assigned or not assigned to a given user.")
+ public boolean isAssigned( )
+ {
+ return assigned;
+ }
+
+ public void setAssigned( boolean assigned )
+ {
+ this.assigned = assigned;
+ }
+
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ BaseRoleInfo that = (BaseRoleInfo) o;
+
+ return id.equals( that.id );
+ }
+
+ @Schema( description = "If true, the role is assignable to users or roles. Otherwise, it can be used only as parent role.")
+ public boolean isAssignable()
+ {
+ return assignable;
+ }
+
+ public void setAssignable( boolean assignable )
+ {
+ this.assignable = assignable;
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ return id.hashCode( );
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "BaseRoleInfo{" );
+ sb.append( "id='" ).append( id ).append( '\'' );
+ sb.append( ", name='" ).append( name ).append( '\'' );
+ sb.append( ", description='" ).append( description ).append( '\'' );
+ sb.append( ", permanent=" ).append( permanent );
+ sb.append( ", modelId='" ).append( modelId ).append( '\'' );
+ sb.append( ", resource='" ).append( resource ).append( '\'' );
+ sb.append( ", isTemplateInstance=" ).append( isTemplateInstance );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+
+ @Schema(description = "Application id, where this role belongs to. This is only filled by certain REST methods.")
+ public String getApplicationId( )
+ {
+ return applicationId;
+ }
+
+ public void setApplicationId( String applicationId )
+ {
+ this.applicationId = applicationId;
+ }
+
+ public boolean isChild( )
+ {
+ return isChild;
+ }
+
+ public void setChild( boolean child )
+ {
+ isChild = child;
+ }
+
+ @XmlTransient
+ public boolean isNotChild() {
+ return !isChild;
+ }
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseUserInfo.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseUserInfo.java
new file mode 100644
index 0000000..7903a1c
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/BaseUserInfo.java
@@ -0,0 +1,67 @@
+package org.apache.archiva.redback.rest.api.model.v2;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlElement;
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+@Schema( name = "BaseUserInfo", description = "Basic user information" )
+public class BaseUserInfo implements Serializable
+{
+ private static final long serialVersionUID = 4643187400578104895L;
+ protected String userId;
+ private String id;
+
+
+ public BaseUserInfo( )
+ {
+ }
+
+ public BaseUserInfo( String id , String userId )
+ {
+ this.userId = userId;
+ this.id = id;
+ }
+
+ @Schema( name = "user_id", description = "The user id" )
+ @XmlElement( name = "user_id" )
+ public String getUserId( )
+ {
+ return userId;
+ }
+
+ public void setUserId( String userId )
+ {
+ this.userId = userId;
+ }
+
+ @Schema( description = "User id that is unique over all user managers" )
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/Role.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/Role.java
new file mode 100644
index 0000000..f5909a9
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/Role.java
@@ -0,0 +1,104 @@
+package org.apache.archiva.redback.rest.api.model.v2;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used for role update. Contains only the role attributes, that can be updated.
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+@Schema(name="Role",description="Role attributes that are used for updating a role")
+public class Role implements Serializable
+{
+ private static final long serialVersionUID = 3238571295658509062L;
+
+ protected String name;
+ protected String id;
+ protected String description;
+ protected boolean permanent = false;
+ /**
+ * The ids of all the assigned users.
+ */
+ protected List<BaseUserInfo> assignedUsers = new ArrayList<>( 0 );
+
+ @Schema(description = "The role name")
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ @Schema( description = "A description of the role" )
+ public String getDescription( )
+ {
+ return description;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ @Schema( description = "True, if this role cannot be deleted.")
+ public boolean isPermanent()
+ {
+ return permanent;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ this.permanent = permanent;
+ }
+
+ @Schema(description = "The identifier of this role")
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema( description = "List of user ids that are assigned to this role.")
+ public List<BaseUserInfo> getAssignedUsers( )
+ {
+ return assignedUsers;
+ }
+
+ public void setAssignedUsers( List<BaseUserInfo> assignedUsers )
+ {
+ this.assignedUsers = assignedUsers;
+ }
+
+ public void addAssignedUser( BaseUserInfo id) {
+ this.assignedUsers.add( id );
+ }
+
+
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleInfo.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleInfo.java
new file mode 100644
index 0000000..aa77836
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleInfo.java
@@ -0,0 +1,182 @@
+package org.apache.archiva.redback.rest.api.model.v2;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import org.apache.archiva.redback.rbac.Role;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Result object for role information.
+ *
+ * @author Martin Stockhammer
+ * @since 3.0
+ */
+@XmlRootElement( name = "role" )
+@Schema(name="RoleInfo",description = "Information about role")
+public class RoleInfo extends BaseRoleInfo
+ implements Serializable
+{
+ private static final long serialVersionUID = -3506615158923923845L;
+
+ /**
+ * Field childRoleNames
+ */
+ private List<String> childRoleIds = new ArrayList<>(0);
+
+ /**
+ * Field permissions
+ */
+ private List<Permission> permissions = new ArrayList<>(0);
+
+ /**
+ * The names of all parent roles
+ */
+ private List<String> parentRoleIds = new ArrayList<>(0);
+
+ /**
+ * The ids of all the assigned users.
+ */
+ protected List<BaseUserInfo> assignedUsers = new ArrayList<>( 0 );
+
+ @Schema( description = "List of user ids that are assigned to this role.")
+ public List<BaseUserInfo> getAssignedUsers( )
+ {
+ return assignedUsers;
+ }
+
+ public void setAssignedUsers( List<BaseUserInfo> assignedUsers )
+ {
+ this.assignedUsers = assignedUsers;
+ }
+
+ public void addAssignedUser( BaseUserInfo id) {
+ this.assignedUsers.add( id );
+ }
+
+ public RoleInfo()
+ {
+ // no op
+ }
+
+
+ public static RoleInfo of( Role rbacRole) {
+ RoleInfo role = BaseRoleInfo.of( rbacRole, new RoleInfo( ) );
+ return role;
+ }
+
+ @XmlTransient
+ @Override
+ public List<BaseRoleInfo> getChildren( )
+ {
+ return super.getChildren( );
+ }
+
+ @Schema( description = "List of names of children roles")
+ public List<String> getChildRoleIds()
+ {
+ return childRoleIds;
+ }
+
+ public void setChildRoleIds( List<String> childRoleIds )
+ {
+ this.childRoleIds = childRoleIds;
+ }
+
+ @Schema( description = "List of permissions assigned to this role.")
+ public List<Permission> getPermissions()
+ {
+ return permissions;
+ }
+
+ public void setPermissions( List<Permission> permissions )
+ {
+ this.permissions = permissions;
+ }
+
+ @Schema(description = "List of names of roles that are parents of this role.")
+ public List<String> getParentRoleIds()
+ {
+ return parentRoleIds;
+ }
+
+ public void setParentRoleIds( List<String> parentRoleIds )
+ {
+ this.parentRoleIds = parentRoleIds;
+ }
+
+ @Override
+ public boolean isChild( )
+ {
+ return getParentRoleIds( ).size( ) > 0;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getName( ) != null ? getName( ).hashCode() : 0;
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "RoleInfo{" );
+ sb.append( "name='" ).append( getName( ) ).append( '\'' );
+ sb.append( ", id='" ).append( getId( ) ).append( '\'' );
+ sb.append( ", description='" ).append( getDescription( ) ).append( '\'' );
+ sb.append( ", assignable=" ).append( assignable );
+ sb.append( ", childRoleNames=" ).append( childRoleIds );
+ sb.append( ", permissions=" ).append( permissions );
+ sb.append( ", parentRoleNames=" ).append( parentRoleIds );
+ sb.append( ", assignedUsers=" ).append( assignedUsers );
+ sb.append( ", permanent=" ).append( isPermanent( ) );
+ sb.append( ", modelId='" ).append( modelId ).append( '\'' );
+ sb.append( ", resource='" ).append( resource ).append( '\'' );
+ sb.append( ", isTemplateInstance=" ).append( isTemplateInstance );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ RoleInfo role = (RoleInfo) o;
+
+ return Objects.equals( getName( ), role.getName( ) );
+
+ }
+
+
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleTree.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleTree.java
new file mode 100644
index 0000000..1af65fd
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/RoleTree.java
@@ -0,0 +1,74 @@
+package org.apache.archiva.redback.rest.api.model.v2;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Information about roles of a application.
+ *
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+@Schema(name="RoleTree",description = "Tree of roles defined. The root roles have no parent. Each role may have children recursively.")
+public class RoleTree implements Serializable
+{
+ private static final long serialVersionUID = 6893397477073625729L;
+
+ String userId;
+ Map<String, Application> applications;
+ List<BaseRoleInfo> rootRoles;
+
+ @Schema(description = "The user id for which the assigned flags are set on the roles.")
+ public String getUserId( )
+ {
+ return userId;
+ }
+
+ public void setUserId( String userId )
+ {
+ this.userId = userId;
+ }
+
+ @Schema(description = "Information about the applications that define roles. The keys of the map are the application ids.")
+ public Map<String, Application> getApplications( )
+ {
+ return applications;
+ }
+
+ public void setApplications( Map<String, Application> applications )
+ {
+ this.applications = applications;
+ }
+
+
+ @Schema(description = "The list of roles directly assigned to this application. Roles may contain children roles.")
+ public List<BaseRoleInfo> getRootRoles( )
+ {
+ return rootRoles;
+ }
+
+ public void setRootRoles( List<BaseRoleInfo> rootRoles )
+ {
+ this.rootRoles = rootRoles;
+ }
+
+
+}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/UserInfo.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/UserInfo.java
index 274848c..c6043d3 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/UserInfo.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/model/v2/UserInfo.java
@@ -2,13 +2,11 @@ package org.apache.archiva.redback.rest.api.model.v2;
import io.swagger.v3.oas.annotations.media.Schema;
-import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
-import java.util.List;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -31,14 +29,11 @@ import java.util.List;
@XmlRootElement( name = "user" )
@Schema(name="User", description = "User information data")
-public class UserInfo
+public class UserInfo extends BaseUserInfo
implements Serializable
{
private static final long serialVersionUID = 822423853981984867L;
- private String id;
-
- private String userId;
private String fullName;
@@ -125,18 +120,6 @@ public class UserInfo
}
- @Schema( name = "user_id", description = "The user id" )
- @XmlElement( name = "user_id" )
- public String getUserId( )
- {
- return userId;
- }
-
- public void setUserId( String userId )
- {
- this.userId = userId;
- }
-
@Schema( description = "The full name of the user" )
public String getFullName( )
{
@@ -282,22 +265,11 @@ public class UserInfo
this.validationToken = validationToken;
}
- @Schema( description = "User id that is unique over all user managers")
- public String getId( )
- {
- return id;
- }
-
- public void setId( String id )
- {
- this.id = id;
- }
-
@Override
public String toString()
{
return "User{" +
- "username='" + userId + '\'' +
+ "username='" + getUserId( ) + '\'' +
", fullName='" + fullName + '\'' +
", email='" + email + '\'' +
", validated=" + validated +
@@ -328,7 +300,7 @@ public class UserInfo
UserInfo user = (UserInfo) o;
- if ( !userId.equals( user.userId ) )
+ if ( !getUserId( ).equals( user.getUserId( ) ) )
{
return false;
}
@@ -339,6 +311,6 @@ public class UserInfo
@Override
public int hashCode()
{
- return userId.hashCode();
+ return getUserId( ).hashCode();
}
}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java
index 82143f4..bbb2502 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/RoleService.java
@@ -20,6 +20,7 @@ package org.apache.archiva.redback.rest.api.services.v2;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -31,7 +32,6 @@ import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.Application;
import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
import org.apache.archiva.redback.rest.api.model.RedbackRestError;
-import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.Role;
import org.apache.archiva.redback.rest.api.model.User;
import org.apache.archiva.redback.rest.api.model.VerificationStatus;
@@ -40,14 +40,19 @@ import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.PATCH;
import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import java.util.List;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@@ -60,15 +65,12 @@ import static org.apache.archiva.redback.rest.api.Constants.DEFAULT_PAGE_LIMIT;
@Tag(name = "v2")
@Tag(name = "v2/Roles")
@SecurityRequirement(name = "BearerAuth")
-public interface RoleManagementService
+public interface RoleService
{
- /**
- * @since 2.0
- */
@Path( "" )
@GET
- @Produces( { MediaType.APPLICATION_JSON } )
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
@Operation( summary = "Returns all roles defined. The result is paged.",
parameters = {
@@ -99,75 +101,209 @@ public interface RoleManagementService
@QueryParam("order") @DefaultValue( "asc" ) String order)
throws RedbackServiceException;
- @Path( "createTemplatedRole" )
+ @Path( "{roleId}" )
@GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus createTemplatedRole( @QueryParam( "templateId" ) String templateId,
- @QueryParam( "resource" ) String resource )
+ @Operation( summary = "Returns information about a specific role. Use HTTP HEAD method for checking, if the resource exists.",
+ security = {
+ @SecurityRequirement(
+ name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If role was found in the database",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RoleInfo.class))
+ ),
+ @ApiResponse( responseCode = "404", description = "Role does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class ))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ RoleInfo getRole( @PathParam( "roleId" ) String roleId )
throws RedbackServiceException;
- /**
- * removes a role corresponding to the role Id that was manufactured with the given resource
- *
- * it also removes any user assignments for that role
- *
- * @param templateId
- * @param resource
- */
- @Path( "removeTemplatedRole" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "{roleId}" )
+ @HEAD
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus removeTemplatedRole( @QueryParam( "templateId" ) String templateId,
- @QueryParam( "resource" ) String resource )
+ @Operation( summary = "Returns information about a specific role. Use HTTP HEAD method for checking, if the resource exists.",
+ security = {
+ @SecurityRequirement(
+ name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If role was found in the database"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class ))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ Response checkRole( @PathParam( "roleId" ) String roleId )
throws RedbackServiceException;
/**
- * allows for a role coming from a template to be renamed effectively swapping out the bits of it that
- * were labeled with the oldResource with the newResource
- *
- * it also manages any user assignments for that role
+ * Moves a templated role from one resource to another resource
+ * @TODO: Not sure, if it makes sense to keep the child template at the source. Shouldn't we move the childs too?
*
- * @param templateId
- * @param oldResource
- * @param newResource
+ * @param templateId the template identifier
+ * @param oldResource the resource of the current role
+ * @param newResource the resource of the new role
*/
- @Path( "updateRole" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "template/{templateId}/{oldResource}/moveto/{newResource}" )
+ @POST
+ @Produces( {APPLICATION_JSON} )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus updateRole( @QueryParam( "templateId" ) String templateId, @QueryParam( "oldResource" ) String oldResource,
- @QueryParam( "newResource" ) String newResource )
+ @Operation( summary = "Moves a templated role from one resource to another resource. If the template has child templates," +
+ " then child instances will be created on for the destination resource. But the child instances on the source are not deleted.",
+ security = {
+ @SecurityRequirement(
+ name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "201",
+ description = "If user creation was successful",
+ headers = {
+ @Header( name="Location", description = "The URL of the moved role", schema = @Schema(type="string"))
+ },
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RoleInfo.class))
+ ),
+ @ApiResponse( responseCode = "404", description = "The source role does not exist" ),
+ @ApiResponse( responseCode = "303", description = "The destination role exists already" ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission to move the role.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+
+ }
+ )
+ RoleInfo moveTemplatedRole( @PathParam( "templateId" ) String templateId, @PathParam( "oldResource" ) String oldResource,
+ @PathParam( "newResource" ) String newResource )
+ throws RedbackServiceException;
+
+ @Path( "template/{templateId}/{resource}" )
+ @HEAD
+ @Produces( { APPLICATION_JSON} )
+ @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ @Operation( summary = "Checks, if a instance of the role template exists for the given resource",
+ security = {
+ @SecurityRequirement(
+ name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the role instance exists"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class ))
+ ),
+ @ApiResponse( responseCode = "403", description = "Authenticated user is not permitted to gather the information",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ Response checkTemplateRole( @PathParam( "templateId" ) String templateId,
+ @PathParam( "resource" ) String resource )
throws RedbackServiceException;
+ @Path( "template/{templateId}/{resource}" )
+ @PUT
+ @Produces( { APPLICATION_JSON } )
+ @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ @Operation( summary = "Creates a role instance from a template for the given resource",
+ security = {
+ @SecurityRequirement(
+ name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION
+ )
+ },
+ responses = {
+ @ApiResponse( responseCode = "201",
+ description = "If user creation was successful",
+ headers = {
+ @Header( name = "Location", description = "The URL of the created role", schema = @Schema( type = "string" ) )
+ },
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RoleInfo.class ) )
+ ),
+ @ApiResponse( responseCode = "200",
+ description = "If the role instance existed before and was updated",
+ headers = {
+ @Header( name = "Location", description = "The URL of the updated role", schema = @Schema( type = "string" ) )
+ },
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RoleInfo.class ) )
+ ),
+ @ApiResponse( responseCode = "404", description = "The template does not exist" ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for role creation.",
+ content = @Content( mediaType = APPLICATION_JSON, schema = @Schema( implementation = RedbackRestError.class ) ) )
+
+ }
+ )
+ RoleInfo createTemplatedRole( @PathParam( "templateId" ) String templateId,
+ @PathParam( "resource" ) String resource )
+ throws RedbackServiceException;
/**
- * Assigns the role indicated by the roleId to the given principal
+ * Removes a role corresponding to the role Id that was manufactured with the given resource
+ * it also removes any user assignments for that role
*
- * @param roleId
- * @param principal
+ * @param templateId
+ * @param resource
*/
- @Path( "assignRole" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "template/{templateId}/{resource}" )
+ @DELETE
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus assignRole( @QueryParam( "roleId" ) String roleId, @QueryParam( "principal" ) String principal )
+ @Operation( summary = "Deletes a role template instance",
+ security = {
+ @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If role deletion was successful"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for deletion.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ Response removeTemplatedRole( @PathParam( "templateId" ) String templateId,
+ @PathParam( "resource" ) String resource )
throws RedbackServiceException;
+
/**
- * Assigns the role indicated by the roleName to the given principal
+ * Assigns the role indicated by the roleId to the given principal
*
- * @param roleName
- * @param principal
- * @throws RedbackServiceException
+ * @param roleId
+ * @param userId
*/
- @Path( "assignRoleByName" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "{roleId}/assign/{userId}" )
+ @PUT
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus assignRoleByName( @QueryParam( "roleName" ) String roleName, @QueryParam( "principal" ) String principal )
+ @Operation( summary = "Assigns a role to a given user",
+ security = {
+ @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the role was assigned"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for role assignment.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ RoleInfo assignRole( @PathParam( "roleId" ) String roleId, @PathParam( "userId" ) String userId )
throws RedbackServiceException;
/**
@@ -179,11 +315,25 @@ public interface RoleManagementService
* @param resource
* @param principal
*/
- @Path( "assignTemplatedRole" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "template/{templateId}/{resource}/assign/{userId}" )
+ @POST
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus assignTemplatedRole( @QueryParam( "templateId" ) String templateId,
+ @Operation( summary = "Assigns a template role instance to a given user",
+ security = {
+ @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the role instance was assigned"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role instance does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for role assignment.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ RoleInfo assignTemplatedRole( @QueryParam( "templateId" ) String templateId,
@QueryParam( "resource" ) String resource,
@QueryParam( "principal" ) String principal )
throws RedbackServiceException;
@@ -195,161 +345,53 @@ public interface RoleManagementService
* @param principal
* @throws RedbackServiceException
*/
- @Path( "unassignRole" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus unassignRole( @QueryParam( "roleId" ) String roleId, @QueryParam( "principal" ) String principal )
- throws RedbackServiceException;
-
- /**
- * Unassigns the role indicated by the role name from the given principal
- *
- * @param roleName
- * @param principal
- * @throws RedbackServiceException
- */
- @Path( "unassignRoleByName" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "{roleId}/{userId}" )
+ @DELETE
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus unassignRoleByName( @QueryParam( "roleName" ) String roleName, @QueryParam( "principal" ) String principal )
- throws RedbackServiceException;
-
- /**
- * true of a role exists with the given roleId
- *
- * @param roleId
- * @return
- * @throws RedbackServiceException
- */
- @Path( "roleExists" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- AvailabilityStatus roleExists( @QueryParam( "roleId" ) String roleId )
- throws RedbackServiceException;
-
- /**
- * true of a role exists with the given roleId
- *
- * @param templateId
- * @param resource
- * @return
- * @throws RedbackServiceException
- */
- @Path( "templatedRoleExists" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- AvailabilityStatus templatedRoleExists( @QueryParam( "templateId" ) String templateId,
- @QueryParam( "resource" ) String resource )
+ @Operation( summary = "Removes a role assignment for the given role and user",
+ security = {
+ @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the role assignment was removed"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role instance does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for role assignment.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ RoleInfo unassignRole( @QueryParam( "roleId" ) String roleId, @QueryParam( "principal" ) String principal )
throws RedbackServiceException;
/**
- * Check a role template is complete in the RBAC store.
+ * Updates a role. Attributes that are empty or null will be ignored.
*
- * @param templateId the templated role
- * @param resource the resource to verify
- * @throws RedbackServiceException
- */
- @Path( "verifyTemplatedRole" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- VerificationStatus verifyTemplatedRole( @QueryParam( "templateId" ) String templateId,
- @QueryParam( "resource" ) String resource )
- throws RedbackServiceException;
-
- /**
- * @since 1.4
- */
- @Path( "getEffectivelyAssignedRoles/{username}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- List<Role> getEffectivelyAssignedRoles( @PathParam( "username" ) String username )
- throws RedbackServiceException;
-
-
-
-
- /**
- * @since 2.0
- */
- @Path( "detailledAllRoles" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- List<Role> getDetailedAllRoles()
- throws RedbackServiceException;
-
-
- /**
- * @since 2.0
- */
- @Path( "getApplications/{username}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- List<Application> getApplications( @PathParam( "username" ) String username )
- throws RedbackServiceException;
-
-
- /**
- * @since 2.0
+ * @since 3.0
*/
- @Path( "getRole/{roleName}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
+ @Path( "{roleId}" )
+ @PATCH
+ @Produces( { APPLICATION_JSON } )
@RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- Role getRole( @PathParam( "roleName" ) String roleName )
- throws RedbackServiceException;
-
- /**
- * @since 2.0
- */
- @Path( "updateRoleDescription" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus updateRoleDescription( @QueryParam( "roleName" ) String roleName,
- @QueryParam( "roleDescription" ) String description )
- throws RedbackServiceException;
-
- /**
- * update users assigned to a role
- * @since 2.0
- */
- @Path( "updateRoleUsers" )
- @POST
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus updateRoleUsers( Role role )
- throws RedbackServiceException;
-
- /**
- * @since 2.0
- */
- @Path( "getApplicationRoles/{username}" )
- @GET
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- List<ApplicationRoles> getApplicationRoles( @PathParam( "username" ) String username )
- throws RedbackServiceException;
+ @Operation( summary = "Creates or updates the given role",
+ security = {
+ @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "If the update was successful"
+ ),
+ @ApiResponse( responseCode = "404", description = "Role does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for role assignment.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ RoleInfo updateRole( @QueryParam("roleId") String roleId, Role role )
+ throws RedbackServiceException;
- /**
- * update roles assigned to a user
- * @since 2.0
- */
- @Path( "updateUserRoles" )
- @POST
- @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
- @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
- ActionStatus updateUserRoles( User user )
- throws RedbackServiceException;
}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java
index f6415bb..243ca6e 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java
+++ b/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/services/v2/UserService.java
@@ -31,12 +31,15 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
+import org.apache.archiva.redback.rest.api.model.Application;
import org.apache.archiva.redback.rest.api.model.RedbackRestError;
-import org.apache.archiva.redback.rest.api.model.v2.Permission;
+import org.apache.archiva.redback.rest.api.model.v2.RoleTree;
import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
+import org.apache.archiva.redback.rest.api.model.v2.Permission;
import org.apache.archiva.redback.rest.api.model.v2.PingResult;
import org.apache.archiva.redback.rest.api.model.v2.RegistrationKey;
+import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
import org.apache.archiva.redback.rest.api.model.v2.SelfUserData;
import org.apache.archiva.redback.rest.api.model.v2.User;
import org.apache.archiva.redback.rest.api.model.v2.UserInfo;
@@ -54,6 +57,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
import java.util.Collection;
import java.util.List;
@@ -594,4 +598,59 @@ public interface UserService
)
VerificationStatus validateUserRegistration( @PathParam( "userId" ) String userId, @PathParam( "key" ) String key )
throws RedbackServiceException;
+
+
+ /**
+ * Returns all roles for a given user id. Recurses all child roles.
+ *
+ * @since 3.0
+ */
+ @Path( "{userId}/roles" )
+ @GET
+ @Produces( { MediaType.APPLICATION_JSON } )
+ @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ @Operation( summary = "Returns a list of all roles effectively assigned to the given user.",
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "The list of roles assigned to the given user",
+ content = @Content(mediaType = APPLICATION_JSON, array = @ArraySchema(schema =
+ @Schema(implementation = org.apache.archiva.redback.rest.api.model.v2.RoleInfo.class )))
+ ),
+ @ApiResponse( responseCode = "404", description = "User does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for retrieving the information.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ List<RoleInfo> getEffectivelyAssignedRoles( @PathParam( "userId" ) String username )
+ throws RedbackServiceException;
+
+
+ /**
+ * @since 3.0
+ */
+ @Path( "{userId}/roletree" )
+ @GET
+ @Produces( { APPLICATION_JSON } )
+ @RedbackAuthorization( permissions = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ @Operation( summary = "Returns a list of all roles that are assigned, or can be assigned to the given user. "+
+ "This method sets the 'assigned' flag on all returned role objects.",
+ security = {
+ @SecurityRequirement( name = RedbackRoleConstants.USER_MANAGEMENT_RBAC_ADMIN_OPERATION )
+ },
+ responses = {
+ @ApiResponse( responseCode = "200",
+ description = "The list of roles separated by application that are assigned or assignable for the given user",
+ content = @Content(mediaType = APPLICATION_JSON, array = @ArraySchema(schema =
+ @Schema(implementation = Application.class )))
+ ),
+ @ApiResponse( responseCode = "404", description = "User does not exist",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) ),
+ @ApiResponse( responseCode = "403", description = "The authenticated user has not the permission for retrieving the information.",
+ content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(implementation = RedbackRestError.class )) )
+ }
+ )
+ RoleTree getRoleTree( @PathParam( "userId" ) String username )
+ throws RedbackServiceException;
+
}
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultRoleManagementService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultRoleManagementService.java
index a80439b..40ec9a3 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultRoleManagementService.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultRoleManagementService.java
@@ -29,7 +29,6 @@ import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.Application;
import org.apache.archiva.redback.rest.api.model.ApplicationRoles;
-import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
import org.apache.archiva.redback.rest.api.model.ErrorMessage;
import org.apache.archiva.redback.rest.api.model.Role;
import org.apache.archiva.redback.rest.api.model.RoleTemplate;
@@ -127,7 +126,7 @@ public class DefaultRoleManagementService
{
try
{
- roleManager.updateRole( templateId, oldResource, newResource );
+ roleManager.moveTemplatedRole( templateId, oldResource, newResource );
}
catch ( RoleManagerException e )
{
@@ -391,7 +390,7 @@ public class DefaultRoleManagementService
org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRole( roleName );
Role role = new Role( rbacRole );
- Map<String, ? extends org.apache.archiva.redback.rbac.Role> parentRoles = rbacManager.getParentRoles( rbacRole );
+ Map<String, ? extends org.apache.archiva.redback.rbac.Role> parentRoles = rbacManager.getParentRoleNames( rbacRole );
for ( String parentRoleName : parentRoles.keySet() )
{
role.getParentRoleNames().add( parentRoleName );
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/BaseRedbackService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/BaseRedbackService.java
new file mode 100644
index 0000000..63318bb
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/BaseRedbackService.java
@@ -0,0 +1,145 @@
+package org.apache.archiva.redback.rest.services.v2;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.redback.rbac.RBACManager;
+import org.apache.archiva.redback.rbac.RbacManagerException;
+import org.apache.archiva.redback.rbac.Role;
+import org.apache.archiva.redback.rest.api.MessageKeys;
+import org.apache.archiva.redback.rest.api.model.ErrorMessage;
+import org.apache.archiva.redback.rest.api.model.v2.BaseUserInfo;
+import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
+import org.apache.archiva.redback.users.User;
+import org.apache.archiva.redback.users.UserManager;
+import org.apache.archiva.redback.users.UserManagerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Named;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+public class BaseRedbackService
+{
+ private static final Logger log = LoggerFactory.getLogger( BaseRedbackService.class );
+
+ protected RBACManager rbacManager;
+ protected UserManager userManager;
+
+ public BaseRedbackService( @Named( value = "rbacManager#default" ) RBACManager rbacManager, @Named( value = "userManager#default" ) UserManager userManager )
+ {
+ this.rbacManager = rbacManager;
+ this.userManager = userManager;
+ }
+
+ protected RoleInfo getRoleInfo( org.apache.archiva.redback.rbac.Role rbacRole ) throws RedbackServiceException
+ {
+ try
+ {
+ RoleInfo role = RoleInfo.of( rbacRole );
+ role.setParentRoleIds( getParentRoles( rbacRole ) );
+ role.setChildRoleIds( getChildRoles( rbacRole ) );
+ role.setAssignedUsers( getAssignedUsersRecursive( rbacRole ) );
+ return role;
+ }
+ catch ( RbacManagerException e )
+ {
+ log.error( "Error while retrieving role information {}", e.getMessage( ), e );
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+ protected List<String> getParentRoles( org.apache.archiva.redback.rbac.Role rbacRole ) throws RbacManagerException
+ {
+ return new ArrayList<>( rbacManager.getParentRoleIds( rbacRole ).keySet( ));
+ }
+
+ protected List<String> getChildRoles( Role rbacRole) throws RbacManagerException
+ {
+ return new ArrayList<>( rbacManager.getChildRoleIds( rbacRole ).keySet( ) );
+ }
+
+ protected List<BaseUserInfo> getAssignedUsersRecursive( org.apache.archiva.redback.rbac.Role rbacRole ) throws RbacManagerException
+ {
+ try
+ {
+ return rbacManager.getUserAssignmentsForRoles( recurseRoles( rbacRole ).map( role -> role.getName( ) ).collect( Collectors.toList( ) ) )
+ .stream( ).map( assignment -> getUserInfo( assignment.getPrincipal( ) ) ).collect( Collectors.toList( ) );
+ }
+ catch ( RuntimeException e )
+ {
+ log.error( "Could not recurse roles for assignments {}", e.getMessage( ) );
+ throw new RbacManagerException( e.getCause( ) );
+ }
+ }
+
+ private Stream<Role> recurseRoles( Role startRole )
+ {
+ return Stream.concat( Stream.of( startRole ), getParentRoleStream( startRole ).flatMap( this::recurseRoles ) ).distinct( );
+ }
+
+ private Stream<? extends Role> getParentRoleStream( Role role )
+ {
+ try
+ {
+ return rbacManager.getParentRoleNames( role ).values( ).stream( );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+ BaseUserInfo getUserInfo( String userId )
+ {
+ try
+ {
+ User user = userManager.findUser( userId );
+ return new BaseUserInfo( user.getId( ), user.getUsername( ) );
+ }
+ catch ( UserManagerException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+ protected Optional<RoleInfo> getRoleInfoOptional( Role rbacRole )
+ {
+ try
+ {
+ RoleInfo role = RoleInfo.of( rbacRole );
+ role.setParentRoleIds( getParentRoles( rbacRole ) );
+ role.setChildRoleIds( getChildRoles( rbacRole ) );
+ role.setAssignedUsers( getAssignedUsersRecursive( rbacRole ) );
+ return Optional.of( role );
+ }
+ catch ( RbacManagerException e )
+ {
+ log.error( "Error while retrieving role information {}", e.getMessage( ), e );
+ return Optional.empty( );
+ }
+ }
+}
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
index c512194..a495d42 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultGroupService.java
@@ -61,6 +61,7 @@ import java.util.stream.Collectors;
* @author Martin Stockhammer
* @since 3.0
*/
+@SuppressWarnings( "SpringJavaAutowiredFieldsWarningInspection" )
@Service("v2.groupService#rest")
public class DefaultGroupService
implements GroupService
@@ -85,7 +86,10 @@ public class DefaultGroupService
@Named(value = "ldapConnectionFactory#configurable")
private LdapConnectionFactory ldapConnectionFactory;
- private static final Group getGroupFromLdap( LdapGroup ldapGroup ) {
+ public DefaultGroupService( ) {
+ }
+
+ private static Group getGroupFromLdap( LdapGroup ldapGroup ) {
Group group = new Group( );
group.setName( ldapGroup.getName() );
group.setUniqueName( ldapGroup.getDn() );
@@ -128,7 +132,7 @@ public class DefaultGroupService
* be found, it will set "" for the uniqueName
*
* @return the list of mapping
- * @throws RedbackServiceException
+ * @throws RedbackServiceException if there was an error retrieving the mapping data
*/
@Override
public List<GroupMapping> getGroupMappings()
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java
new file mode 100644
index 0000000..a4077b7
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultRoleService.java
@@ -0,0 +1,434 @@
+package org.apache.archiva.redback.rest.services.v2;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
+import org.apache.archiva.redback.integration.util.RoleSorter;
+import org.apache.archiva.redback.rbac.Permission;
+import org.apache.archiva.redback.rbac.RBACManager;
+import org.apache.archiva.redback.rbac.RbacManagerException;
+import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
+import org.apache.archiva.redback.rbac.Resource;
+import org.apache.archiva.redback.rest.api.MessageKeys;
+import org.apache.archiva.redback.rest.api.model.ErrorMessage;
+import org.apache.archiva.redback.rest.api.model.Role;
+import org.apache.archiva.redback.rest.api.model.RoleTemplate;
+import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
+import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
+import org.apache.archiva.redback.rest.api.services.v2.RoleService;
+import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal;
+import org.apache.archiva.redback.rest.services.RedbackRequestInformation;
+import org.apache.archiva.redback.role.RoleExistsException;
+import org.apache.archiva.redback.role.RoleManager;
+import org.apache.archiva.redback.role.RoleManagerException;
+import org.apache.archiva.redback.role.RoleNotFoundException;
+import org.apache.archiva.redback.role.model.ModelTemplate;
+import org.apache.archiva.redback.users.User;
+import org.apache.archiva.redback.users.UserManager;
+import org.apache.archiva.redback.users.UserManagerException;
+import org.apache.archiva.redback.users.UserNotFoundException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.3
+ */
+@Service("v2.roleService#rest")
+public class DefaultRoleService extends BaseRedbackService
+ implements RoleService
+{
+
+ private Logger log = LoggerFactory.getLogger( DefaultRoleService.class );
+
+ private RoleManager roleManager;
+
+ @Context
+ private HttpServletRequest httpServletRequest;
+
+ @Context
+ private HttpServletResponse httpServletResponse;
+
+ @Context
+ private UriInfo uriInfo;
+
+ private static final String[] DEFAULT_SEARCH_FIELDS = {"name", "description"};
+ private static final Map<String, BiPredicate<String, org.apache.archiva.redback.rbac.Role>> FILTER_MAP = new HashMap<>( );
+ private static final Map<String, Comparator<org.apache.archiva.redback.rbac.Role>> ORDER_MAP = new HashMap<>( );
+ private static final QueryHelper<org.apache.archiva.redback.rbac.Role> QUERY_HELPER;
+
+ static
+ {
+
+ QUERY_HELPER = new QueryHelper<>( FILTER_MAP, ORDER_MAP, DEFAULT_SEARCH_FIELDS );
+ QUERY_HELPER.addStringFilter( "name", org.apache.archiva.redback.rbac.Role::getName );
+ QUERY_HELPER.addStringFilter( "description", org.apache.archiva.redback.rbac.Role::getDescription );
+ QUERY_HELPER.addBooleanFilter( "assignable", org.apache.archiva.redback.rbac.Role::isAssignable );
+
+ // The simple Comparator.comparing(attribute) is not null safe
+ // As there are attributes that may have a null value, we have to use a comparator with nullsLast(naturalOrder)
+ // and the wrapping Comparator.nullsLast(Comparator.comparing(attribute)) does not work, because the attribute is not checked by the nullsLast-Comparator
+ QUERY_HELPER.addNullsafeFieldComparator( "name", org.apache.archiva.redback.rbac.Role::getName );
+ QUERY_HELPER.addNullsafeFieldComparator( "id", org.apache.archiva.redback.rbac.Role::getId );
+ QUERY_HELPER.addNullsafeFieldComparator( "resource", org.apache.archiva.redback.rbac.Role::getResource );
+ QUERY_HELPER.addNullsafeFieldComparator( "assignable", org.apache.archiva.redback.rbac.Role::isAssignable );
+ QUERY_HELPER.addNullsafeFieldComparator( "template_instance", org.apache.archiva.redback.rbac.Role::isTemplateInstance );
+ }
+
+ @Inject
+ public DefaultRoleService( RoleManager roleManager,
+ @Named(value = "rbacManager#default") RBACManager rbacManager,
+ @Named(value = "userManager#default") UserManager userManager )
+ {
+ super( rbacManager, userManager );
+ this.roleManager = roleManager;
+
+ log.debug( "use rbacManager impl: {}", rbacManager.getClass().getName() );
+ log.debug( "use userManager impl: {}", userManager.getClass().getName() );
+ }
+
+ @Override
+ public PagedResult<RoleInfo> getAllRoles( String searchTerm, Integer offset, Integer limit, List<String> orderBy, String order ) throws RedbackServiceException
+ {
+ boolean ascending = !"desc".equals( order );
+ try
+ {
+ // UserQuery does not work here, because the configurable user manager does only return the query for
+ // the first user manager in the list. So we have to fetch the whole role list
+ List<? extends org.apache.archiva.redback.rbac.Role> rawRoles = rbacManager.getAllRoles( );
+ Predicate<org.apache.archiva.redback.rbac.Role> filter = QUERY_HELPER.getQueryFilter( searchTerm );
+ long size = rawRoles.stream( ).filter( filter ).count( );
+ List<RoleInfo> users = rawRoles.stream( )
+ .filter( filter )
+ .sorted( QUERY_HELPER.getComparator( orderBy, ascending ) ).skip( offset ).limit( limit )
+ .map( role -> {
+ try
+ {
+ return Optional.of( getRoleInfo( role ) );
+ }
+ catch ( RedbackServiceException e )
+ {
+ return Optional.<RoleInfo>empty();
+ }
+ } ).filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect( Collectors.toList( ) );
+ return new PagedResult<>( (int) size, offset, limit, users );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL , e.getMessage( )) );
+ }
+
+ }
+
+ @Override
+ public RoleInfo getRole( String roleId ) throws RedbackServiceException
+ {
+ try
+ {
+ org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRoleById( roleId );
+ RoleInfo role = getRoleInfo( rbacRole );
+ return role;
+ }
+ catch ( RbacObjectNotFoundException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND, roleId ), 404 );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public Response checkRole( String roleId ) throws RedbackServiceException
+ {
+ try
+ {
+ org.apache.archiva.redback.rbac.Role rbacRole = rbacManager.getRoleById( roleId );
+ if (rbacRole==null) {
+ return Response.status( 404 ).build();
+ } else
+ {
+ return Response.ok( ).build( );
+ }
+ }
+ catch ( RbacObjectNotFoundException e )
+ {
+ return Response.status( 404 ).build();
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+
+
+ @Override
+ public RoleInfo moveTemplatedRole( String templateId, String oldResource, String newResource )
+ throws RedbackServiceException
+ {
+ try
+ {
+ if (StringUtils.isEmpty( templateId ) || StringUtils.isEmpty( oldResource ) || StringUtils.isEmpty( newResource )) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND ), 404 );
+ }
+ boolean sourceExists = roleManager.templatedRoleExists( templateId, oldResource );
+ if (!sourceExists) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_NOT_FOUND, templateId, oldResource ), 404 );
+ }
+ boolean destExists = roleManager.templatedRoleExists( templateId, newResource );
+ if (destExists) {
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(newResource).build( ).normalize().toString() );
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_EXISTS, templateId, newResource ), 303 );
+ }
+ String roleId = roleManager.moveTemplatedRole( templateId, oldResource, newResource );
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(newResource).build( ).normalize().toString() );
+ httpServletResponse.setStatus( 201 );
+ return getRoleInfo( rbacManager.getRoleById( roleId ) );
+ }
+ catch ( RoleExistsException e ) {
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(newResource).build( ).normalize().toString() );
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_EXISTS, templateId, newResource ), 303 );
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+
+ @Override
+ public Response checkTemplateRole( String templateId, String resource )
+ throws RedbackServiceException
+ {
+ try
+ {
+ if (roleManager.templatedRoleExists( templateId, resource )) {
+ return Response.ok( ).build( );
+ } else {
+ return Response.status( 404 ).build();
+ }
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( e.getMessage() );
+ }
+
+ }
+
+ @Override
+ public RoleInfo createTemplatedRole( String templateId, String resource )
+ throws RedbackServiceException
+ {
+ if (StringUtils.isEmpty( templateId )) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND ), 404 );
+ }
+ if (StringUtils.isEmpty( resource )) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND ), 404 );
+ }
+ try
+ {
+ boolean exists = roleManager.templatedRoleExists( templateId, resource );
+ String roleId = roleManager.createTemplatedRole( templateId, resource );
+ httpServletResponse.setHeader( "Location", uriInfo.getAbsolutePathBuilder().path("../../..").path(roleId).build( ).normalize().toString() );
+ if (exists)
+ {
+ httpServletResponse.setStatus( 200 );
+ } else {
+ httpServletResponse.setStatus( 201 );
+ }
+ return getRoleInfo( rbacManager.getRoleById( roleId ) );
+ } catch (RoleNotFoundException e) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND, templateId, resource ), 404 );
+ } catch (RoleExistsException e) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_EXISTS, templateId, resource ), 303 );
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+ @Override
+ public Response removeTemplatedRole( String templateId, String resource )
+ throws RedbackServiceException
+ {
+
+ try
+ {
+ roleManager.removeTemplatedRole( templateId, resource );
+ return Response.ok( ).build( );
+ }
+ catch ( RoleNotFoundException e ) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_INSTANCE_NOT_FOUND, templateId, resource ), 404 );
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+
+
+ @Override
+ public RoleInfo assignRole( String roleId, String userId )
+ throws RedbackServiceException
+ {
+ try
+ {
+ userManager.findUser( userId );
+ roleManager.assignRole( roleId, userId );
+ return getRoleInfo( rbacManager.getRoleById( roleId ) );
+ }
+ catch ( RoleNotFoundException e ) {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLE_NOT_FOUND, e.getMessage( ) ), 404 );
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_ROLEMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ catch ( UserNotFoundException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_USER_NOT_FOUND, e.getMessage( ) ), 404 );
+ }
+ catch ( UserManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_USERMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ catch ( RbacObjectNotFoundException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+
+ @Override
+ public RoleInfo assignTemplatedRole( String templateId, String resource, String principal )
+ throws RedbackServiceException
+ {
+ try
+ {
+ roleManager.assignTemplatedRole( templateId, resource, principal );
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( e.getMessage() );
+ }
+ return null;
+ }
+
+ @Override
+ public RoleInfo unassignRole( String roleId, String principal )
+ throws RedbackServiceException
+ {
+ try
+ {
+ roleManager.unassignRole( roleId, principal );
+ }
+ catch ( RoleManagerException e )
+ {
+ throw new RedbackServiceException( e.getMessage() );
+ }
+ return null;
+ }
+
+ @Override
+ public RoleInfo updateRole( String roleId, Role role ) throws RedbackServiceException
+ {
+ return null;
+ }
+
+
+
+// public List<Role> getEffectivelyAssignedRoles( String username )
+// throws RedbackServiceException
+// {
+// if ( StringUtils.isEmpty( username ) )
+// {
+// throw new RedbackServiceException( new ErrorMessage( "user.cannot.be.null" ) );
+// }
+// try
+// {
+// List<? extends org.apache.archiva.redback.rbac.Role> roles =
+// filterAssignableRoles( rbacManager.getEffectivelyAssignedRoles( username ) );
+//
+// List<Role> effectivelyAssignedRoles = new ArrayList<Role>( roles.size() );
+//
+// for ( org.apache.archiva.redback.rbac.Role r : roles )
+// {
+// effectivelyAssignedRoles.add( new Role( r ) );
+// }
+//
+// Collections.sort( effectivelyAssignedRoles, RoleComparator.INSTANCE );
+//
+// return effectivelyAssignedRoles;
+// }
+// catch ( RbacManagerException rme )
+// {
+// // ignore, this can happen when the user has no roles assigned
+// }
+// return new ArrayList<Role>( 0 );
+// }
+
+
+ //----------------------------------------------------------------
+ // Internal methods
+ //----------------------------------------------------------------
+
+
+}
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
index b465809..5561d5c 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/DefaultUserService.java
@@ -41,17 +41,22 @@ import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.rbac.RbacManagerException;
+import org.apache.archiva.redback.rbac.Role;
import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.rest.api.MessageKeys;
import org.apache.archiva.redback.rest.api.model.ActionStatus;
import org.apache.archiva.redback.rest.api.model.ErrorMessage;
+import org.apache.archiva.redback.rest.api.model.v2.Application;
import org.apache.archiva.redback.rest.api.model.v2.AvailabilityStatus;
+import org.apache.archiva.redback.rest.api.model.v2.BaseRoleInfo;
import org.apache.archiva.redback.rest.api.model.v2.Operation;
import org.apache.archiva.redback.rest.api.model.v2.PagedResult;
import org.apache.archiva.redback.rest.api.model.v2.Permission;
import org.apache.archiva.redback.rest.api.model.v2.PingResult;
import org.apache.archiva.redback.rest.api.model.v2.RegistrationKey;
import org.apache.archiva.redback.rest.api.model.v2.Resource;
+import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.apache.archiva.redback.rest.api.model.v2.RoleTree;
import org.apache.archiva.redback.rest.api.model.v2.SelfUserData;
import org.apache.archiva.redback.rest.api.model.v2.User;
import org.apache.archiva.redback.rest.api.model.v2.UserInfo;
@@ -65,6 +70,7 @@ import org.apache.archiva.redback.rest.services.interceptors.RedbackPrincipal;
import org.apache.archiva.redback.rest.services.utils.PasswordValidator;
import org.apache.archiva.redback.role.RoleManager;
import org.apache.archiva.redback.role.RoleManagerException;
+import org.apache.archiva.redback.role.model.ModelApplication;
import org.apache.archiva.redback.system.SecuritySession;
import org.apache.archiva.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.UserManager;
@@ -91,17 +97,19 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
@Service( "v2.userService#rest" )
-public class DefaultUserService
+public class DefaultUserService extends BaseRedbackService
implements UserService
{
@@ -113,6 +121,7 @@ public class DefaultUserService
private static final String[] DEFAULT_SEARCH_FIELDS = {"user_id", "full_name", "email"};
private static final Map<String, BiPredicate<String, org.apache.archiva.redback.users.User>> FILTER_MAP = new HashMap<>( );
private static final Map<String, Comparator<org.apache.archiva.redback.users.User>> ORDER_MAP = new HashMap<>( );
+ private static final QueryHelper<org.apache.archiva.redback.users.User> QUERY_HELPER;
static
{
@@ -133,10 +142,9 @@ public class DefaultUserService
FILTER_MAP.put( "user_id", ( String q, org.apache.archiva.redback.users.User u ) -> StringUtils.containsIgnoreCase( u.getUsername( ), q ) );
FILTER_MAP.put( "full_name", ( String q, org.apache.archiva.redback.users.User u ) -> StringUtils.containsIgnoreCase( u.getFullName( ), q ) );
FILTER_MAP.put( "email", ( String q, org.apache.archiva.redback.users.User u ) -> StringUtils.containsIgnoreCase( u.getEmail( ), q ) );
- }
-
- private UserManager userManager;
+ QUERY_HELPER = new QueryHelper<>( FILTER_MAP, ORDER_MAP, DEFAULT_SEARCH_FIELDS );
+ }
private SecuritySystem securitySystem;
@@ -174,9 +182,10 @@ public class DefaultUserService
@Inject
private Mailer mailer;
+
@Inject
- @Named( value = "rbacManager#default" )
- private RBACManager rbacManager;
+ @Named( value = "v2.roleService#rest" )
+ private DefaultRoleService roleManagementService;
private HttpAuthenticator httpAuthenticator;
@@ -196,10 +205,11 @@ public class DefaultUserService
private SecurityContext securityContext;
@Inject
- public DefaultUserService( @Named( value = "userManager#default" ) UserManager userManager,
+ public DefaultUserService(@Named( value = "rbacManager#default" ) RBACManager rbacManager,
+ @Named( value = "userManager#default" ) UserManager userManager ,
SecuritySystem securitySystem )
{
- this.userManager = userManager;
+ super( rbacManager, userManager );
this.securitySystem = securitySystem;
}
@@ -220,7 +230,8 @@ public class DefaultUserService
public UserInfo createUser( User user )
throws RedbackServiceException
{
- if (user==null) {
+ if ( user == null )
+ {
throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_USER_ID_EMPTY ), 422 );
}
UserInfo result;
@@ -311,7 +322,8 @@ public class DefaultUserService
public void deleteUser( String userId )
throws RedbackServiceException
{
- if (StringUtils.isEmpty( userId )) {
+ if ( StringUtils.isEmpty( userId ) )
+ {
throw new RedbackServiceException( MessageKeys.ERR_USER_ID_EMPTY, 404 );
}
@@ -355,7 +367,8 @@ public class DefaultUserService
public UserInfo getUser( String userId )
throws RedbackServiceException
{
- if (StringUtils.isEmpty( userId)) {
+ if ( StringUtils.isEmpty( userId ) )
+ {
throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_USER_ID_EMPTY ), 404 );
}
try
@@ -377,55 +390,6 @@ public class DefaultUserService
}
}
- Comparator<org.apache.archiva.redback.users.User> getAttributeComparator( String attributeName )
- {
- return ORDER_MAP.get( attributeName );
- }
-
- Comparator<org.apache.archiva.redback.users.User> getComparator( List<String> orderBy, boolean ascending )
- {
- if ( ascending )
- {
- return orderBy.stream( ).map( ( String name ) -> getAttributeComparator( name ) ).filter( Objects::nonNull ).reduce( Comparator::thenComparing ).get( );
- }
- else
- {
- return orderBy.stream( ).map( ( String name ) -> getAttributeComparator( name ) == null ? null : getAttributeComparator( name ).reversed( ) ).filter( Objects::nonNull ).reduce( Comparator::thenComparing ).get( );
- }
- }
-
- static Predicate<org.apache.archiva.redback.users.User> getFilter( final String attribute, final String queryToken )
- {
- if ( FILTER_MAP.containsKey( attribute ) )
- {
- return ( org.apache.archiva.redback.users.User u ) -> FILTER_MAP.get( attribute ).test( queryToken, u );
- }
- else
- {
- return Arrays.stream( DEFAULT_SEARCH_FIELDS )
- .map( att -> getFilter( att, queryToken ) ).reduce( Predicate::or ).get( );
- }
- }
-
- Predicate<org.apache.archiva.redback.users.User> getUserFilter( String queryTerms )
- {
- return Arrays.stream( queryTerms.split( "\\s+" ) )
- .map( s -> {
- if ( s.contains( ":" ) )
- {
- String attr = StringUtils.substringBefore( s, ":" );
- String term = StringUtils.substringAfter( s, ":" );
- return getFilter( attr, term );
- }
- else
- {
- return Arrays.stream( DEFAULT_SEARCH_FIELDS )
- .map( att -> getFilter( att, s ) ).reduce( Predicate::or ).get( );
- }
- }
- ).reduce( Predicate::or ).get( );
- }
-
@Override
public PagedResult<UserInfo> getUsers( String q, Integer offset,
Integer limit, List<String> orderBy, String order )
@@ -437,11 +401,11 @@ public class DefaultUserService
// UserQuery does not work here, because the configurable user manager does only return the query for
// the first user manager in the list. So we have to fetch the whole user list
List<? extends org.apache.archiva.redback.users.User> rawUsers = userManager.getUsers( );
- Predicate<org.apache.archiva.redback.users.User> filter = getUserFilter( q );
+ Predicate<org.apache.archiva.redback.users.User> filter = QUERY_HELPER.getQueryFilter( q );
long size = rawUsers.stream( ).filter( filter ).count( );
List<UserInfo> users = rawUsers.stream( )
.filter( filter )
- .sorted( getComparator( orderBy, ascending ) ).skip( offset ).limit( limit )
+ .sorted( QUERY_HELPER.getComparator( orderBy, ascending ) ).skip( offset ).limit( limit )
.map( user -> getRestUser( user ) )
.collect( Collectors.toList( ) );
return new PagedResult<>( (int) size, offset, limit, users );
@@ -975,6 +939,101 @@ public class DefaultUserService
}
@Override
+ public List<RoleInfo> getEffectivelyAssignedRoles( String username ) throws RedbackServiceException
+ {
+ try
+ {
+ return rbacManager.getEffectivelyAssignedRoles( username ).stream( )
+ .filter( org.apache.archiva.redback.rbac.Role::isAssignable )
+ .map( this::getRoleInfoOptional )
+ .filter( Optional::isPresent )
+ .map(Optional::get).collect( Collectors.toList());
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+ private static final Application toApplication( ModelApplication app )
+ {
+ Application application = new Application( );
+ application.setId( app.getId( ) );
+ application.setVersion( app.getVersion( ) );
+ application.setDescription( app.getDescription( ) == null ? "" :app.getDescription() );
+ application.setLongDescription( app.getLongDescription( ) == null ? "" : app.getLongDescription( ) );
+ return application;
+ }
+
+ private List<Application> getAllApplications( )
+ {
+ return roleManager.getModel( ).getApplications( ).stream( ).map( DefaultUserService::toApplication ).collect( Collectors.toList( ) );
+ }
+
+
+ @Override
+ public RoleTree getRoleTree( final String username ) throws RedbackServiceException
+ {
+ final Map<String, String> roleApplicationMap = roleManager.getModel( ).getApplications( ).stream( )
+ .flatMap( modelApplication -> modelApplication.getRoles( ).stream( ).map( role -> {
+ BaseRoleInfo roleInfo = new BaseRoleInfo( );
+ roleInfo.setId( role.getId( ) );
+ roleInfo.setApplicationId( modelApplication.getId( ) );
+ return roleInfo;
+ } ) ).collect( Collectors.toMap( BaseRoleInfo::getId, BaseRoleInfo::getApplicationId ) );
+
+ try
+ {
+ final Set<String> assignedRoleNames = new HashSet( rbacManager.getUserAssignment( username ).getRoleNames( ) );
+ // We have to reuse the BaseRoleInfo objects, because the roles are not returned starting from the roots
+ final Map<String, BaseRoleInfo> roleNameCache = new HashMap<>( );
+ List<BaseRoleInfo> roleList = rbacManager.getAllRoles( ).stream( ).flatMap( this::flattenRole ).map( role ->
+ {
+ BaseRoleInfo roleInfo = roleNameCache.computeIfAbsent( role.getName( ), s -> new BaseRoleInfo( ) );
+ // Setting the role data, as there may be child role objects that are not completely initialized
+ roleInfo = BaseRoleInfo.of( role, roleInfo );
+ roleInfo.setApplicationId( roleApplicationMap.get( role.getId( ) ) );
+ roleInfo.setAssigned( assignedRoleNames.contains( role.getName( ) ) );
+ roleInfo.setChildren( role.getChildRoleNames( ).stream( )
+ .map( roleName ->
+ {
+ BaseRoleInfo childRoleInfo = roleNameCache.computeIfAbsent( roleName, s -> BaseRoleInfo.ofName( roleName ) );
+ childRoleInfo.setChild( true );
+ return childRoleInfo;
+ } )
+ .collect( Collectors.toList( ) ) );
+ return roleInfo;
+ } ).collect( Collectors.toList( ) );
+ RoleTree roleTree = new RoleTree( );
+ roleTree.setApplications( getAllApplications( ).stream( ).collect( Collectors.toMap( Application::getId, Function.identity( ) ) ) );
+ roleTree.setRootRoles( roleList.stream( ).filter( BaseRoleInfo::isNotChild ).collect( Collectors.toList( ) ) );
+ roleTree.setUserId( username );
+ return roleTree;
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RedbackServiceException( ErrorMessage.of( MessageKeys.ERR_RBACMANAGER_FAIL, e.getMessage( ) ) );
+ }
+ }
+
+ private Stream<Role> flattenRole( Role role )
+ {
+ return Stream.concat( Stream.of( role ), this.getChildren( role ).flatMap( this::flattenRole ) ).distinct( );
+ }
+
+ private Stream<? extends Role> getChildren( Role role )
+ {
+ try
+ {
+ return rbacManager.getChildRoleNames( role ).values( ).stream( );
+ }
+ catch ( RbacManagerException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+ @Override
public Collection<Operation> getUserOperations( String userName )
throws RedbackServiceException
{
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/QueryHelper.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/QueryHelper.java
new file mode 100644
index 0000000..ba417aa
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/v2/QueryHelper.java
@@ -0,0 +1,168 @@
+package org.apache.archiva.redback.rest.services.v2;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ *
+ * Helper class that returns combined filter and comparison objects for ordering.
+ *
+ * The query term may be consist of simple query terms separated by whitespace or attribute queries
+ * in the form <code>attribute:query</code>, which means only the attribute is searched for the query string.
+ * <br />
+ * Example:
+ * <dl>
+ * <dt>`user1 test`</dt>
+ * <dd>
+ * searches for the tokens user1 and test in the default attributes.
+ * </dd>
+ * <dt>`user1 name:test`</dt>
+ * <dd>searches for the token user1 in the default attributes and for the token test in the attribute name.</dd>
+ * </dl>
+ *
+ *
+ * @since 3.0
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+public class QueryHelper<T>
+{
+
+ private final Map<String, BiPredicate<String, T>> FILTER_MAP;
+ private final Map<String, Comparator<T>> ORDER_MAP;
+ private final String[] DEFAULT_SEARCH_FIELDS;
+ private final Predicate<T> DEFAULT_FILTER = ( T att ) -> false;
+
+
+ /**
+ * Creates a new query helper with the given filters and comparators.
+ *
+ * @param filterMap a map of filters, where the key is the attribute name and the value is a predicate that matches
+ * the filter value and the object instance.
+ * @param orderMap a map of comparators, where key is the attribute name and the value is a comparator for the given
+ * object instance
+ * @param defaultSearchFields A array of attribute names, that are used as default search fields.
+ */
+ public QueryHelper(Map<String, BiPredicate<String, T>> filterMap, Map<String, Comparator<T>> orderMap,
+ String[] defaultSearchFields)
+ {
+ this.FILTER_MAP = filterMap;
+ this.DEFAULT_SEARCH_FIELDS = defaultSearchFields;
+ this.ORDER_MAP = new HashMap<>( orderMap );
+ }
+
+ public <U extends Comparable<? super U>> void addNullsafeFieldComparator( String fieldName, Function<? super T, U> keyExtractor) {
+ ORDER_MAP.put( fieldName, Comparator.comparing( keyExtractor, Comparator.nullsLast( Comparator.naturalOrder( ) ) ) );
+ }
+
+ public void addStringFilter(String attribute, Function<? super T, String> keyExtractor) {
+ this.FILTER_MAP.put( attribute, ( String q, T r ) -> StringUtils.containsIgnoreCase( keyExtractor.apply( r ), q ) );
+ }
+
+ public void addBooleanFilter(String attribute, Function<? super T, Boolean> keyExtractor) {
+ this.FILTER_MAP.put( attribute, ( String q, T r ) -> Boolean.valueOf( q ) == keyExtractor.apply( r ) );
+ }
+
+ /**
+ * Get the comparator for a specific attribute.
+ * @param attributeName the name of the attribute.
+ * @return
+ */
+ Comparator<T> getAttributeComparator( String attributeName )
+ {
+ return ORDER_MAP.get( attributeName );
+ }
+
+ /**
+ * Get the combined order for the given attributes in the given order.
+ *
+ * @param orderBy the attributes to compare. The first attribute in the list will be used first for comparing.
+ * @param ascending
+ * @return
+ */
+ Comparator<T> getComparator( List<String> orderBy, boolean ascending )
+ {
+ if ( ascending )
+ {
+ return orderBy.stream( ).map( ( String name ) -> getAttributeComparator( name ) ).filter( Objects::nonNull )
+ .reduce( Comparator::thenComparing )
+ .orElseThrow( () -> new IllegalArgumentException( "No attribute ordering found" ) );
+ }
+
+ else
+ {
+ return orderBy.stream( ).map( ( String name ) -> getAttributeComparator( name ) == null ? null : getAttributeComparator( name )
+ .reversed( ) ).filter( Objects::nonNull ).reduce( Comparator::thenComparing )
+ .orElseThrow( () -> new IllegalArgumentException( "No attribute ordering found" ) );
+ }
+ }
+
+ /**
+ * Returns a query filter for a specific attribute and query token.
+ * @param attribute the attribute name to filter for.
+ * @param queryToken the search token.
+ * @return The predicate used to filter the token
+ */
+ Predicate<T> getAttributeQueryFilter( final String attribute, final String queryToken )
+ {
+ if ( FILTER_MAP.containsKey( attribute ) )
+ {
+ return ( T u ) -> FILTER_MAP.get( attribute ).test( queryToken, u );
+ }
+ else
+ {
+ return DEFAULT_FILTER;
+ }
+ }
+
+ /**
+ * Returns the combined query filter for the given query terms.
+ * The query terms may be either simple strings separated by whitespace or use the
+ * <code>attribute:query</code> syntax, that searches only the attribute for the query term.
+ * @param queryTerms the query string
+ * @return the combined query filter
+ */
+ Predicate<T> getQueryFilter( String queryTerms )
+ {
+ return Arrays.stream( queryTerms.split( "\\s+" ) )
+ .map( s -> {
+ if ( s.contains( ":" ) )
+ {
+ String attr = StringUtils.substringBefore( s, ":" );
+ String term = StringUtils.substringAfter( s, ":" );
+ return getAttributeQueryFilter( attr, term );
+ }
+ else
+ {
+ return Arrays.stream( DEFAULT_SEARCH_FIELDS )
+ .map( att -> getAttributeQueryFilter( att, s ) ).reduce( Predicate::or ).get( );
+ }
+ }
+ ).reduce( Predicate::or ).get( );
+ }
+
+}
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
index 5041bc4..ff90b95 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
+++ b/redback-integrations/redback-rest/redback-rest-services/src/main/resources/META-INF/spring-context.xml
@@ -93,7 +93,7 @@
<jaxrs:serviceBeans>
<ref bean="v2.userService#rest"/>
<ref bean="v2.authenticationService#rest"/>
- <ref bean="roleManagementService#rest"/>
+ <ref bean="v2.roleService#rest"/>
<ref bean="utilServices#rest"/>
<ref bean="passwordService#rest"/>
<ref bean="v2.groupService#rest"/>
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
index 2adc1e7..1523387 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/AbstractNativeRestServices.java
@@ -128,7 +128,7 @@ public abstract class AbstractNativeRestServices
}
- private String getServiceBasePath( )
+ protected String getServiceBasePath( )
{
return "/v2/redback";
}
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java
new file mode 100644
index 0000000..f3105d3
--- /dev/null
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeRoleServiceTest.java
@@ -0,0 +1,505 @@
+package org.apache.archiva.redback.rest.services.v2;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.restassured.response.Response;
+import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.http.ContentType.JSON;
+import static org.apache.archiva.redback.rest.api.Constants.DEFAULT_PAGE_LIMIT;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Martin Stockhammer <ma...@apache.org>
+ */
+@ExtendWith( SpringExtension.class )
+@ContextConfiguration(
+ locations = {"classpath:/ldap-spring-test.xml"} )
+@TestInstance( TestInstance.Lifecycle.PER_CLASS )
+@Tag( "rest-native" )
+@TestMethodOrder( MethodOrderer.Random.class )
+@DisplayName( "Native REST tests for V2 RoleService" )
+public class NativeRoleServiceTest extends AbstractNativeRestServices
+{
+ @Override
+ protected String getServicePath( )
+ {
+ return "/roles";
+ }
+
+ @BeforeAll
+ void setup( ) throws Exception
+ {
+ super.setupNative( );
+ }
+
+ @AfterAll
+ void destroy( ) throws Exception
+ {
+ super.shutdownNative( );
+ }
+
+ private String getUserServicePath()
+ {
+ return new StringBuilder( )
+ .append( getContextRoot( ) )
+ .append( getServiceBasePath( ) )
+ .append( "/users" ).toString( );
+ }
+
+
+
+ @Test
+ void createTemplatedRole( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 201 ).extract( ).response( );
+ assertNotNull( response );
+ RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
+ assertNotNull( response.getHeader( "Location" ) );
+ assertTrue( response.getHeader( "Location" ).endsWith( "/roles/" + roleInfo.getId( ) ) );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .head( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 200 );
+ // Repository observer is child template of repository-manager and will be created too
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .head( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 200 );
+
+ }
+ finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 200 );
+ }
+ }
+
+ @Test
+ void createTemplatedRoleWithNonexistentTemplate( )
+ {
+ String token = getAdminToken( );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/abcdefg/repository01" )
+ .then( ).statusCode( 404 );
+ }
+
+ @Test
+ void deleteTemplatedRole( )
+ {
+ String token = getAdminToken( );
+ try
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repository05" )
+ .then( ).statusCode( 201 ).extract( ).response( );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 404 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository05" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository05" )
+ .then( ).statusCode( 404 );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository05" )
+ .then( ).statusCode( 200 );
+
+ }
+ }
+
+ @Test
+ void checkTemplatedRole() {
+ String token = getAdminToken( );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 201 );
+ try {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .head( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 200 );
+
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .head( "archiva-repository-observer.repository01" )
+ .then( ).statusCode( 200 );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 200 );
+ }
+
+ }
+
+
+ @Nested
+ @DisplayName( "Test Role queries" )
+ @ContextConfiguration(
+ locations = {"classpath:/ldap-spring-test.xml"} )
+ @TestInstance( TestInstance.Lifecycle.PER_CLASS )
+ class TestRoleRetrieval
+ {
+ int roleInstances = 3;
+ String token;
+
+ @BeforeAll
+ void initRoles( )
+ {
+ this.token = getAdminToken( );
+ for ( int i = 0; i < roleInstances; i++ )
+ {
+ String suffix = String.format( "%03d", i );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repo" + suffix )
+ .then( ).statusCode( 201 ).extract( ).response( );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-observer/repo" + suffix )
+ .then( ).statusCode( anyOf( equalTo( 200 ), equalTo( 201 ) ) ).extract( ).response( );
+ }
+ }
+
+ @Test
+ void getMultipleRolesWithoutParams( )
+ {
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).get( ).then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ List<RoleInfo> roleData = response.body( ).jsonPath( ).getList( "data", RoleInfo.class );
+ assertNotNull( roleData );
+ assertEquals( roleInstances * 2 + 9, roleData.size( ) );
+ assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( DEFAULT_PAGE_LIMIT ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( roleInstances * 2 + 9 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
+
+ }
+
+ @Test
+ void getMultipleRolesWithPaging( )
+ {
+ HashMap<String, String> params = new HashMap<>( );
+ params.put( "limit", Integer.toString( 10 ) );
+ params.put( "offset", Integer.toString( 1 ) );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).params( params ).get( ).then( ).statusCode( 200 ).extract( ).response( );
+ List<RoleInfo> userData = response.body( ).jsonPath( ).getList( "data", RoleInfo.class );
+ assertNotNull( userData );
+ response.getBody( ).jsonPath( ).prettyPrint( );
+ assertEquals( 10, userData.size( ) );
+ assertEquals( Integer.valueOf( 1 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( 10 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( roleInstances * 2 + 9 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
+ }
+
+ @Test
+ void getMultipleUsersWithPagingOrderByIdAndResource( )
+ {
+ HashMap<String, Object> params = new HashMap<>( );
+ params.put( "limit", Integer.toString( 8 ) );
+ params.put( "offset", Integer.toString( 5 ) );
+ params.put( "orderBy", Arrays.asList( "id", "resource" ) );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).params( params ).get( ).then( ).statusCode( 200 ).extract( ).response( );
+ List<RoleInfo> userData = response.body( ).jsonPath( ).getList( "data", RoleInfo.class );
+ assertNotNull( userData );
+ // admin user has toto@toto.org as email so is after aragorn
+ assertEquals( "repo002", userData.get( 0 ).getResource( ) );
+ assertEquals( "repo000", userData.get( 1 ).getResource( ) );
+ assertEquals( "archiva-repository-observer.repo000", userData.get( 1 ).getId( ) );
+ assertEquals( "archiva-system-administrator", userData.get( 4 ).getId( ) );
+ assertEquals( 8, userData.size( ) );
+ assertEquals( Integer.valueOf( 5 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( 8 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( roleInstances * 2 + 9 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
+ }
+
+ @Test
+ void getMultipleUsersWithPagingOrderByIdAndResourceReverse( )
+ {
+ HashMap<String, Object> params = new HashMap<>( );
+ params.put( "limit", Integer.toString( 7 ) );
+ params.put( "offset", Integer.toString( 1 ) );
+ params.put( "orderBy", Arrays.asList( "id", "resource" ) );
+ params.put( "order", "desc" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).params( params ).get( ).then( ).statusCode( 200 ).extract( ).response( );
+ response.getBody( ).jsonPath( ).prettyPrint( );
+ List<RoleInfo> userData = response.body( ).jsonPath( ).getList( "data", RoleInfo.class );
+ assertNotNull( userData );
+ // admin user has toto@toto.org as email so is after aragorn
+ assertEquals( "system-administrator", userData.get( 0 ).getId( ) );
+ assertEquals( "registered-user", userData.get( 1 ).getId( ) );
+ assertEquals( "guest", userData.get( 2 ).getId( ) );
+ assertEquals( "archiva-repository-observer.repo002", userData.get( 5 ).getId( ) );
+ assertEquals( 7, userData.size( ) );
+ assertEquals( Integer.valueOf( 1 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( 7 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( roleInstances * 2 + 9 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
+ }
+
+ @Test
+ void getMultipleRolesWithPagingAndQuery( )
+ {
+ HashMap<String, String> params = new HashMap<>( );
+ params.put( "limit", Integer.toString( 10 ) );
+ params.put( "offset", Integer.toString( 0 ) );
+ params.put( "order", "asc" );
+ params.put( "q", "system" );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).params( params ).get( ).then( ).statusCode( 200 ).extract( ).response( );
+ List<RoleInfo> userData = response.body( ).jsonPath( ).getList( "data", RoleInfo.class );
+ assertNotNull( userData );
+ assertEquals( 2, userData.size( ) );
+ assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
+ assertEquals( Integer.valueOf( 10 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( 2 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
+
+ }
+
+
+ @AfterAll
+ void cleanupRoles( )
+ {
+ for ( int i = 0; i < roleInstances; i++ )
+ {
+ String suffix = String.format( "%03d", i );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).delete( "template/archiva-repository-manager/repo" + suffix ).then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).delete( "template/archiva-repository-observer/repo" + suffix ).then( ).statusCode( 200 );
+ }
+
+ }
+ }
+
+ @Test
+ void getRole( )
+ {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).get( "archiva-system-administrator" ).then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ RoleInfo roleInfo = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
+ assertNotNull( roleInfo );
+ assertEquals( "archiva-system-administrator", roleInfo.getId( ) );
+ assertEquals( "Archiva System Administrator", roleInfo.getName( ) );
+ }
+
+ @Test
+ void getNonExistingRole( )
+ {
+ String token = getAdminToken( );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).get( "abcdefg" ).then( ).statusCode( 404 );
+ }
+
+ @Test
+ void checkRole() {
+ String token = getAdminToken( );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "archiva-system-administrator" ).then( ).statusCode( 200 ).extract( ).response( );
+ assertEquals(0,response.getBody( ).asByteArray().length);
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "abcdefg" ).then( ).statusCode( 404 );
+
+ }
+
+ @Test
+ void moveRole() {
+ String token = getAdminToken( );
+ try
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 201 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "template/archiva-repository-observer/repository01" ).then( ).statusCode( 200 );
+
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).post( "template/archiva-repository-manager/repository01/moveto/repository02" ).then( ).statusCode( 201 ).extract( ).response( );
+ RoleInfo role = response.getBody( ).jsonPath( ).getObject( "", RoleInfo.class );
+ assertNotNull( role );
+ assertEquals( "archiva-repository-manager.repository02", role.getId( ) );
+ assertEquals( "repository02", role.getResource( ) );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "template/archiva-repository-manager/repository01" ).then( ).statusCode( 404 );
+ // Child templates are copied and not moved
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "template/archiva-repository-observer/repository01" ).then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "template/archiva-repository-observer/repository02" ).then( ).statusCode( 200 );
+
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository02" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository01" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository02" )
+ .then( ).statusCode( 200 );
+
+ }
+
+ }
+
+ @Test
+ void moveRoleToExistingDestination() {
+ String token = getAdminToken( );
+ try
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 201 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "template/archiva-repository-manager/repository02" )
+ .then( ).statusCode( 201 );
+ Response response = given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).redirects( ).follow( false )
+ .post( "template/archiva-repository-manager/repository01/moveto/repository02" ).then( ).statusCode( 303 )
+ .extract( ).response( );
+ System.out.println( response.getHeader( "Location" ) );
+ assertTrue( response.getHeader( "Location" ).endsWith( "/roles/template/archiva-repository-manager/repository02" ) );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( ).head( "template/archiva-repository-manager/repository01" ).then( ).statusCode( 200 );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository01" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-manager/repository02" )
+ .then( ).statusCode( 200 );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .delete( "template/archiva-repository-observer/repository02" )
+ .then( ).statusCode( 200 );
+
+ }
+
+ }
+
+
+ @Test
+ void assignRole() {
+ String token = getAdminToken( );
+ Map<String, Object> jsonAsMap = new HashMap<>( );
+ jsonAsMap.put( "user_id", "aragorn");
+ jsonAsMap.put( "email", "aragorn@lordoftherings.org" );
+ jsonAsMap.put( "full_name", "Aragorn King of Gondor " );
+ jsonAsMap.put( "password", "pAssw0rD" );
+
+ try
+ {
+ given( ).spec( getRequestSpec( token, getUserServicePath() ) ).contentType( JSON )
+ .body( jsonAsMap )
+ .when( )
+ .post( )
+ .then( ).statusCode( 201 );
+
+ Response response = given( ).spec( getRequestSpec( token, getUserServicePath() ) ).contentType( JSON )
+ .when( )
+ .get( "aragorn/roles" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ List<RoleInfo> roles = response.getBody( ).jsonPath( ).getList( "", RoleInfo.class );
+ assertFalse( roles.stream( ).filter( role -> "system-administrator".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
+ given( ).spec( getRequestSpec( token ) ).contentType( JSON )
+ .when( )
+ .put( "system-administrator/assign/aragorn" )
+ .prettyPeek()
+ .then( ).statusCode( 200 );
+ response = given( ).spec( getRequestSpec( token, getUserServicePath() ) ).contentType( JSON )
+ .when( )
+ .get( "aragorn/roles" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ roles = response.getBody( ).jsonPath( ).getList( "", RoleInfo.class );
+ assertTrue( roles.stream( ).filter( role -> "system-administrator".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
+ } finally
+ {
+ given( ).spec( getRequestSpec( token, getUserServicePath() ) ).contentType( JSON )
+ .when( )
+ .delete( "aragorn" ).getBody( );
+ }
+ }
+
+}
diff --git a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
index e8f6cef..4181d27 100644
--- a/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
+++ b/redback-integrations/redback-rest/redback-rest-services/src/test/java/org/apache/archiva/redback/rest/services/v2/NativeUserServiceTest.java
@@ -18,10 +18,13 @@ package org.apache.archiva.redback.rest.services.v2;
* under the License.
*/
+import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
+import org.apache.archiva.redback.rest.api.model.v2.BaseRoleInfo;
import org.apache.archiva.redback.rest.api.model.v2.Operation;
import org.apache.archiva.redback.rest.api.model.v2.Permission;
import org.apache.archiva.redback.rest.api.model.v2.RegistrationKey;
+import org.apache.archiva.redback.rest.api.model.v2.RoleInfo;
import org.apache.archiva.redback.rest.api.model.v2.UserInfo;
import org.apache.archiva.redback.rest.api.model.v2.VerificationStatus;
import org.apache.archiva.redback.rest.services.mock.EmailMessage;
@@ -44,6 +47,7 @@ import java.util.Map;
import static io.restassured.RestAssured.given;
import static io.restassured.http.ContentType.JSON;
+import static org.apache.archiva.redback.rest.api.Constants.DEFAULT_PAGE_LIMIT;
import static org.junit.jupiter.api.Assertions.*;
/**
@@ -87,7 +91,7 @@ public class NativeUserServiceTest extends AbstractNativeRestServices
assertNotNull( userData );
assertEquals( 2, userData.size( ) );
assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
- assertEquals( Integer.valueOf( 1000 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( DEFAULT_PAGE_LIMIT ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
assertEquals( Integer.valueOf( 2 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
}
@@ -134,7 +138,7 @@ public class NativeUserServiceTest extends AbstractNativeRestServices
assertEquals( "admin", userData.get( 0 ).getUserId( ) );
assertEquals( userNum + 2, userData.size( ) );
assertEquals( Integer.valueOf( 0 ), response.body( ).jsonPath( ).get( "pagination.offset" ) );
- assertEquals( Integer.valueOf( 1000 ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
+ assertEquals( Integer.valueOf( DEFAULT_PAGE_LIMIT ), response.body( ).jsonPath( ).get( "pagination.limit" ) );
assertEquals( Integer.valueOf( userNum + 2 ), response.body( ).jsonPath( ).get( "pagination.total_count" ) );
}
@@ -1508,4 +1512,128 @@ public class NativeUserServiceTest extends AbstractNativeRestServices
.then( ).statusCode( 200 );
}
}
+
+ @Test
+ void getUserRoles() {
+ String adminToken = getAdminToken( );
+
+ Map<String, Object> userMap = new HashMap<>( );
+ userMap.put( "user_id", "bilbo" );
+ userMap.put( "email", "bilbo@lordoftherings.org" );
+ userMap.put( "full_name", "Bilbo Beutlin" );
+ userMap.put( "validated", true );
+ userMap.put( "password", "pAssw0rD" );
+ userMap.put( "confirm_password", "pAssw0rD" );
+ given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .body( userMap )
+ .when( )
+ .post( )
+ .then( ).statusCode( 201 );
+
+
+ try
+ {
+ Response response = given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .when( )
+ .get( "bilbo/roles" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ JsonPath jsonPath = response.getBody( ).jsonPath( );
+ List<RoleInfo> roleList = jsonPath.getList( "", RoleInfo.class );
+ assertEquals( 1, roleList.size( ) );
+ assertEquals( "registered-user", roleList.get( 0 ).getId( ) );
+
+ response = given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .when( )
+ .get( "admin/roles" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ jsonPath = response.getBody( ).jsonPath( );
+ roleList = jsonPath.getList( "", RoleInfo.class );
+ jsonPath.prettyPrint( );
+ assertEquals( 4, roleList.size( ) );
+ assertTrue( roleList.stream( ).filter( role -> "system-administrator".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
+ assertTrue( roleList.stream( ).filter( role -> "archiva-global-repository-manager".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
+ assertTrue( roleList.stream( ).filter( role -> "archiva-global-repository-observer".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
+ assertTrue( roleList.stream( ).filter( role -> "user-administrator".equals( role.getId( ) ) ).findAny( ).isPresent( ) );
+
+
+ }
+ finally
+ {
+ given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .delete( "bilbo" )
+ .then( ).statusCode( 200 );
+ }
+ }
+
+ @Test
+ void getRoleTree() {
+ String adminToken = getAdminToken( );
+
+ Map<String, Object> userMap = new HashMap<>( );
+ userMap.put( "user_id", "bilbo" );
+ userMap.put( "email", "bilbo@lordoftherings.org" );
+ userMap.put( "full_name", "Bilbo Beutlin" );
+ userMap.put( "validated", true );
+ userMap.put( "password", "pAssw0rD" );
+ userMap.put( "confirm_password", "pAssw0rD" );
+ given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .body( userMap )
+ .when( )
+ .post( )
+ .then( ).statusCode( 201 );
+
+
+ try
+ {
+ Response response = given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .when( )
+ .get( "bilbo/roletree" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ JsonPath jsonPath = response.getBody( ).jsonPath( );
+ assertTrue( jsonPath.getMap( "applications" ).containsKey( "System" ) );
+ assertTrue( jsonPath.getMap( "applications" ).containsKey( "Archiva" ) );
+ List<BaseRoleInfo> roleList = jsonPath.getList( "root_roles", BaseRoleInfo.class );
+ assertEquals( 3, roleList.size( ) );
+ assertTrue( roleList.stream( ).filter( role -> role.getId( ).equals( "guest" ) ).findFirst( ).isPresent( ) );
+ BaseRoleInfo registered = roleList.stream( ).filter( role -> role.getId( ).equals( "registered-user" ) ).findFirst( ).get( );
+ assertTrue( registered.isAssigned( ) );
+ BaseRoleInfo sysadmin = roleList.stream( ).filter( role -> role.getId( ).equals( "system-administrator" ) ).findFirst( ).get( );
+ assertFalse( sysadmin.isAssigned( ) );
+ assertFalse( sysadmin.isChild( ) );
+ assertEquals( 2, sysadmin.getChildren( ).size( ) );
+ assertTrue( sysadmin.getChildren( ).stream( ).filter( role -> role.getId( ).equals( "user-administrator" ) ).findFirst( ).isPresent( ) );
+
+
+ response = given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .when( )
+ .get( "admin/roletree" )
+ .then( ).statusCode( 200 ).extract( ).response( );
+ assertNotNull( response );
+ System.out.println( response.getBody( ).prettyPrint( ) );
+ jsonPath = response.getBody( ).jsonPath( );
+ assertTrue( jsonPath.getMap( "applications" ).containsKey( "System" ) );
+ assertTrue( jsonPath.getMap( "applications" ).containsKey( "Archiva" ) );
+ roleList = jsonPath.getList( "root_roles", BaseRoleInfo.class );
+ assertEquals( 3, roleList.size( ) );
+ assertTrue( roleList.stream( ).filter( role -> role.getId( ).equals( "guest" ) ).findFirst( ).isPresent( ) );
+ registered = roleList.stream( ).filter( role -> role.getId( ).equals( "registered-user" ) ).findFirst( ).get( );
+ assertFalse( registered.isAssigned( ) );
+ sysadmin = roleList.stream( ).filter( role -> role.getId( ).equals( "system-administrator" ) ).findFirst( ).get( );
+ assertTrue( sysadmin.isAssigned( ) );
+ assertFalse( sysadmin.isChild( ) );
+ assertEquals( 2, sysadmin.getChildren( ).size( ) );
+ assertTrue( sysadmin.getChildren( ).stream( ).filter( role -> role.getId( ).equals( "user-administrator" ) ).findFirst( ).isPresent( ) );
+
+
+ }
+ finally
+ {
+ given( ).spec( getRequestSpec( adminToken ) ).contentType( JSON )
+ .delete( "bilbo" )
+ .then( ).statusCode( 200 );
+ }
+ }
}
diff --git a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRBACManager.java b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRBACManager.java
index 8ace7e6..bdecd29 100644
--- a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRBACManager.java
+++ b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRBACManager.java
@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* AbstractRBACManager
@@ -499,7 +500,7 @@ public abstract class AbstractRBACManager
if ( role.hasChildRoles() )
{
- Map<String, ? extends Role> childRoles = getChildRoles( role );
+ Map<String, ? extends Role> childRoles = getChildRoleNames( role );
Iterator<? extends Role> it = childRoles.values().iterator();
while ( it.hasNext() )
{
@@ -736,11 +737,11 @@ public abstract class AbstractRBACManager
throws RbacObjectInvalidException, RbacManagerException
{
saveRole( childRole );
- role.addChildRoleName( childRole.getName() );
+ role.addChildRole( childRole );
}
@Override
- public Map<String, ? extends Role> getChildRoles( Role role )
+ public Map<String, ? extends Role> getChildRoleNames( Role role )
throws RbacManagerException
{
Map<String, Role> childRoles = new HashMap<String, Role>();
@@ -797,7 +798,64 @@ public abstract class AbstractRBACManager
}
@Override
- public Map<String, ? extends Role> getParentRoles( Role role )
+ public Map<String, ? extends Role> getChildRoleIds( Role role )
+ throws RbacManagerException
+ {
+ Map<String, Role> childRoles = new HashMap<String, Role>();
+
+ boolean childRoleNamesUpdated = false;
+
+ Iterator<String> it = role.getChildRoleIds().listIterator();
+
+ final List<String> updatedChildRoleList = new ArrayList<String>( role.getChildRoleIds().size() );
+
+ while ( it.hasNext() )
+ {
+ String roleId = it.next();
+ try
+ {
+ Role child = getRoleById( roleId );
+ // archiva can change role manager but LDAP can be non writable so in such case
+ // some roles doesn't exists !!
+ if ( child != null )
+ {
+ childRoles.put( child.getId(), child );
+ updatedChildRoleList.add( roleId );
+ }
+ else
+ {
+ log.warn(
+ "error searching role with name '{}' probably some issues when migrating your role manager",
+ roleId );
+ }
+ }
+ catch ( RbacObjectNotFoundException e )
+ {
+ // Found a bad roleName! - trigger new List save
+ //it.remove();
+ childRoleNamesUpdated = true;
+ }
+ catch ( RbacManagerException e )
+ {
+ if ( !( e.getCause() instanceof RbacObjectNotFoundException ) )
+ {
+ throw e;
+ }
+ childRoleNamesUpdated = true;
+ }
+ }
+
+ if ( childRoleNamesUpdated )
+ {
+ role.setChildRoleIds( updatedChildRoleList );
+ saveRole( role );
+ }
+
+ return childRoles;
+ }
+
+ @Override
+ public Map<String, ? extends Role> getParentRoleNames( Role role )
throws RbacManagerException
{
Map<String, Role> parentRoles = new HashMap<String, Role>();
@@ -823,6 +881,23 @@ public abstract class AbstractRBACManager
}
@Override
+ public Map<String, ? extends Role> getParentRoleIds( final Role role ) throws RbacManagerException
+ {
+ return getAllRoles( ).stream( ).filter( r -> !r.getId( ).equals( role.getId( ) ) )
+ .filter( r -> {
+ try
+ {
+ return getEffectiveRoles( r ).stream( ).map( Role::getId ).filter( cRoleId -> cRoleId.equals( role.getId( ) ) ).findAny( ).isPresent( );
+ }
+ catch ( RbacManagerException e )
+ {
+ return false;
+ }
+ }
+ ).distinct().collect( Collectors.toMap( Role::getId, Function.identity( ) ) );
+ }
+
+ @Override
public Set<? extends Role> getEffectiveRoles( Role role )
throws RbacObjectNotFoundException, RbacManagerException
{
diff --git a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRole.java b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRole.java
index a90f66a..5736f5b 100644
--- a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRole.java
+++ b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/AbstractRole.java
@@ -29,7 +29,7 @@ public abstract class AbstractRole
@Override
public boolean hasChildRoles()
{
- return ( getChildRoleNames() != null ) && !getChildRoleNames().isEmpty();
+ return ( getChildRoleIds() != null ) && !getChildRoleIds().isEmpty();
}
/**
@@ -57,4 +57,11 @@ public abstract class AbstractRole
return result;
}
+
+ @Override
+ public void addChildRole( Role child )
+ {
+ addChildRoleName( child.getName() );
+ addChildRoleId( child.getId() );
+ }
}
diff --git a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/RBACManager.java b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/RBACManager.java
index 11b56db..16ac43d 100644
--- a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/RBACManager.java
+++ b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/RBACManager.java
@@ -155,21 +155,39 @@ public interface RBACManager
throws RbacObjectInvalidException, RbacManagerException;
/**
- * Returns all the child roles of a given role.
+ * Returns all the child roles of a given role as (name, role) pairs.
* @param role the parent role
* @return the list of child roles
* @throws RbacManagerException if the access to the backend datastore failed
*/
- Map<String, ? extends Role> getChildRoles( Role role )
+ Map<String, ? extends Role> getChildRoleNames( Role role )
throws RbacManagerException;
/**
- * Returns all the parent roles of a given role.
+ * Returns all the child roles of a given role as (role id, role) pairs.
+ * @param role the parent role
+ * @return the map of child roles as (role id, role) pairs
+ * @throws RbacManagerException if the access to the backend datastore failed
+ */
+ Map<String, ? extends Role> getChildRoleIds( Role role )
+ throws RbacManagerException;
+
+ /**
+ * Returns all the parent roles of a given role as map of (name, role) elements.
* @param role the role to check for parent roles
* @return the list of parent roles that have <code>role</code> als child
* @throws RbacManagerException if the access to the backend datastore failed
*/
- Map<String, ? extends Role> getParentRoles( Role role )
+ Map<String, ? extends Role> getParentRoleNames( Role role )
+ throws RbacManagerException;
+
+ /**
+ * Returns all the parent roles of a given role as map of (id, role) elements.
+ * @param role the role to check for parents roles
+ * @return a map of (role id, role) pairs that have <code>role</code> as child
+ * @throws RbacManagerException if the access to the backend datastore failed
+ */
+ Map<String, ? extends Role> getParentRoleIds( Role role )
throws RbacManagerException;
/**
diff --git a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/Role.java b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/Role.java
index 407be44..f389d82 100644
--- a/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/Role.java
+++ b/redback-rbac/redback-rbac-model/src/main/java/org/apache/archiva/redback/rbac/Role.java
@@ -59,6 +59,24 @@ public interface Role
List<String> getChildRoleNames();
/**
+ * Adds a child role and sets the list of child names and child ids.
+ * @param child the child role
+ */
+ void addChildRole( Role child );
+
+ /**
+ * Adds a child role id
+ * @param id the id
+ */
+ void addChildRoleId( String id );
+
+ /**
+ * Returns the child role ids
+ * @return the list of child role ids
+ */
+ List<String> getChildRoleIds();
+
+ /**
* Convenience method to see if Role has Child Roles.
*
* @return true if child roles exists and has any roles being tracked.
@@ -115,6 +133,12 @@ public interface Role
void setChildRoleNames( List<String> names );
/**
+ * Sets the list of child role ids
+ * @param ids
+ */
+ void setChildRoleIds( List<String> ids );
+
+ /**
* Set the Description
*
* @param description the role description
@@ -220,4 +244,6 @@ public interface Role
* @param resource the resource identifier. Must not be null.
*/
void setResource( String resource );
+
+
}
\ No newline at end of file
diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-cached/src/main/java/org/apache/archiva/redback/rbac/cached/CachedRbacManager.java b/redback-rbac/redback-rbac-providers/redback-rbac-cached/src/main/java/org/apache/archiva/redback/rbac/cached/CachedRbacManager.java
index 8ffc360..7fbbcdd 100644
--- a/redback-rbac/redback-rbac-providers/redback-rbac-cached/src/main/java/org/apache/archiva/redback/rbac/cached/CachedRbacManager.java
+++ b/redback-rbac/redback-rbac-providers/redback-rbac-cached/src/main/java/org/apache/archiva/redback/rbac/cached/CachedRbacManager.java
@@ -291,19 +291,33 @@ public class CachedRbacManager
}
@Override
- public Map<String, ? extends Role> getChildRoles( Role role )
+ public Map<String, ? extends Role> getChildRoleNames( Role role )
throws RbacManagerException
{
log.debug( "NOT CACHED - .getChildRoles(Role)" );
- return this.rbacImpl.getChildRoles( role );
+ return this.rbacImpl.getChildRoleNames( role );
}
@Override
- public Map<String, ? extends Role> getParentRoles( Role role )
+ public Map<String, ? extends Role> getChildRoleIds( Role role ) throws RbacManagerException
+ {
+ log.debug( "NOT CACHED - .getChildRoles(Role)" );
+ return this.rbacImpl.getChildRoleIds( role );
+ }
+
+ @Override
+ public Map<String, ? extends Role> getParentRoleNames( Role role )
throws RbacManagerException
{
log.debug( "NOT CACHED - .getParentRoles(Role)" );
- return this.rbacImpl.getParentRoles( role );
+ return this.rbacImpl.getParentRoleNames( role );
+ }
+
+ @Override
+ public Map<String, ? extends Role> getParentRoleIds( Role role ) throws RbacManagerException
+ {
+ log.debug( "NOT CACHED - .getParentRoles(Role)" );
+ return this.rbacImpl.getParentRoleIds( role );
}
@Override
diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java
index 0c7a9da..8bd3212 100644
--- a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java
+++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java
@@ -35,7 +35,7 @@ import org.apache.archiva.redback.rbac.jpa.model.JpaPermission;
import org.apache.archiva.redback.rbac.jpa.model.JpaResource;
import org.apache.archiva.redback.rbac.jpa.model.JpaRole;
import org.apache.archiva.redback.rbac.jpa.model.JpaUserAssignment;
-import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.archiva.redback.rbac.jpa.model.RoleId;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
@@ -44,9 +44,6 @@ import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -138,8 +135,15 @@ public class JpaRbacManager extends AbstractRBACManager {
@Transactional
@Override
- public Map<String, ? extends Role> getChildRoles(Role role) throws RbacManagerException {
- return super.getChildRoles(role);
+ public Map<String, ? extends Role> getChildRoleNames( Role role) throws RbacManagerException {
+ return super.getChildRoleNames(role);
+ }
+
+ @Transactional
+ @Override
+ public Map<String, ? extends Role> getChildRoleIds( Role role ) throws RbacManagerException
+ {
+ return super.getChildRoleIds( role );
}
@Transactional
@@ -219,7 +223,7 @@ public class JpaRbacManager extends AbstractRBACManager {
throw new RbacPermanentException( "Unable to delete permanent role [" + role.getName() + "]" );
}
final EntityManager em = getEm();
- JpaRole myRole = em.find(JpaRole.class, role.getName());
+ JpaRole myRole = em.find(JpaRole.class, new RoleId( role.getId(), role.getName()));
if (myRole == null) {
throw new RbacObjectNotFoundException("Role not found "+role.getName());
}
diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java
index d21eb6a..7b775ae 100644
--- a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java
+++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java
@@ -21,6 +21,7 @@ package org.apache.archiva.redback.rbac.jpa.model;
import org.apache.archiva.redback.rbac.AbstractRole;
import org.apache.archiva.redback.rbac.Permission;
+import org.apache.archiva.redback.rbac.Role;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
@@ -37,15 +38,17 @@ import java.util.List;
@Table(
name="SECURITY_ROLES"
)
+@IdClass( RoleId.class )
public class JpaRole extends AbstractRole implements Serializable {
private static final Logger log = LoggerFactory.getLogger( JpaRole.class );
private static final long serialVersionUID = 4564608138465995665L;
@Id
- @Column(name="NAME")
+ @Column(name="NAME", unique = true)
private String name;
- @Column(name="ID", unique = true)
+ @Id
+ @Column( name = "ID", unique = true )
private String id;
@Column(name="DESCRIPTION")
private String description;
@@ -75,6 +78,17 @@ public class JpaRole extends AbstractRole implements Serializable {
)
List<String> childRoleNames = new ArrayList<String>();
+ @ElementCollection(fetch = FetchType.EAGER)
+ @OrderColumn(name="INTEGER_IDX",nullable = false)
+ @Column(name="CHILD_IDS")
+ @CollectionTable(
+ name="SECURITY_ROLE_CHILDROLE_ID_MAP",
+ joinColumns = {
+ @JoinColumn(name="ID_OID",referencedColumnName = "ID", nullable = false)
+ }
+ )
+ List<String> childRoleIds = new ArrayList<String>();
+
@Column(name="TEMPLATE_INSTANCE",nullable = false)
private Boolean templateInstance = false;
@@ -102,11 +116,23 @@ public class JpaRole extends AbstractRole implements Serializable {
}
@Override
+ public void addChildRoleId( String id )
+ {
+ this.childRoleIds.add( id );
+ }
+
+ @Override
public List<String> getChildRoleNames() {
return childRoleNames;
}
@Override
+ public List<String> getChildRoleIds( )
+ {
+ return childRoleIds;
+ }
+
+ @Override
public String getDescription() {
return description;
}
@@ -143,6 +169,13 @@ public class JpaRole extends AbstractRole implements Serializable {
}
@Override
+ public void setChildRoleIds( List<String> childRoleIds )
+ {
+ this.childRoleIds.clear();
+ this.childRoleIds.addAll( childRoleIds );
+ }
+
+ @Override
public void setDescription(String description) {
this.description=description;
@@ -245,12 +278,15 @@ public class JpaRole extends AbstractRole implements Serializable {
JpaRole jpaRole = (JpaRole) o;
- return name.equals( jpaRole.name );
+ if ( !name.equals( jpaRole.name ) ) return false;
+ return id.equals( jpaRole.id );
}
@Override
public int hashCode( )
{
- return name.hashCode( );
+ int result = name.hashCode( );
+ result = 31 * result + id.hashCode( );
+ return result;
}
}
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/RoleId.java
similarity index 50%
copy from redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
copy to redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/RoleId.java
index 3faaf8c..f63d77f 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
+++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/RoleId.java
@@ -1,6 +1,4 @@
-package org.apache.archiva.redback.rest.api;
-
-/*
+package org.apache.archiva.redback.rbac.jpa.model;/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -18,12 +16,44 @@ package org.apache.archiva.redback.rest.api;
* under the License.
*/
+import java.io.Serializable;
+
/**
* @author Martin Stockhammer <ma...@apache.org>
*/
-public interface Constants
+public class RoleId implements Serializable
{
- String DEFAULT_PAGE_LIMIT = "1000";
+ private static final long serialVersionUID = -3358026083136193536L;
+ private String id;
+ private String name;
+
+ public RoleId( )
+ {
+ }
+
+ public RoleId( String id, String name )
+ {
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ RoleId roleId = (RoleId) o;
+ if ( !id.equals( roleId.id ) ) return false;
+ return name.equals( roleId.name );
+ }
+ @Override
+ public int hashCode( )
+ {
+ int result = id.hashCode( );
+ result = 31 * result + name.hashCode( );
+ return result;
+ }
}
diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-ldap/src/main/java/org/apache/archiva/redback/rbac/ldap/LdapRbacManager.java b/redback-rbac/redback-rbac-providers/redback-rbac-ldap/src/main/java/org/apache/archiva/redback/rbac/ldap/LdapRbacManager.java
index df05dcf..c5d9e8a 100644
--- a/redback-rbac/redback-rbac-providers/redback-rbac-ldap/src/main/java/org/apache/archiva/redback/rbac/ldap/LdapRbacManager.java
+++ b/redback-rbac/redback-rbac-providers/redback-rbac-ldap/src/main/java/org/apache/archiva/redback/rbac/ldap/LdapRbacManager.java
@@ -60,10 +60,8 @@ import javax.naming.directory.DirContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -474,17 +472,29 @@ public class LdapRbacManager
}
@Override
- public Map<String, ? extends Role> getChildRoles( Role role )
+ public Map<String, ? extends Role> getChildRoleNames( Role role )
throws RbacManagerException
{
- return this.rbacImpl.getChildRoles( role );
+ return this.rbacImpl.getChildRoleNames( role );
}
@Override
- public Map<String, ? extends Role> getParentRoles( Role role )
+ public Map<String, ? extends Role> getChildRoleIds( Role role ) throws RbacManagerException
+ {
+ return this.rbacImpl.getChildRoleIds( role );
+ }
+
+ @Override
+ public Map<String, ? extends Role> getParentRoleNames( Role role )
throws RbacManagerException
{
- return this.rbacImpl.getParentRoles( role );
+ return this.rbacImpl.getParentRoleNames( role );
+ }
+
+ @Override
+ public Map<String, ? extends Role> getParentRoleIds( Role role ) throws RbacManagerException
+ {
+ return this.rbacImpl.getParentRoleIds( role );
}
//
@@ -1241,9 +1251,10 @@ public class LdapRbacManager
private boolean isTemplateInstance=false;
private String resource="";
- private List<Permission> permissions = new ArrayList<Permission>();
+ private List<Permission> permissions = new ArrayList<>();
- private List<String> childRoleNames = new ArrayList<String>();
+ private List<String> childRoleNames = new ArrayList<>();
+ private List<String> childRoleIds = new ArrayList<>( );
private RoleImpl( String name )
{
@@ -1281,6 +1292,18 @@ public class LdapRbacManager
}
@Override
+ public void addChildRoleId( String id )
+ {
+ this.childRoleIds.add( id );
+ }
+
+ @Override
+ public List<String> getChildRoleIds( )
+ {
+ return this.childRoleIds;
+ }
+
+ @Override
public String getDescription()
{
return this.description;
@@ -1323,6 +1346,12 @@ public class LdapRbacManager
}
@Override
+ public void setChildRoleIds( List<String> ids )
+ {
+
+ }
+
+ @Override
public void setDescription( String description )
{
this.description = description;
diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/apache/archiva/redback/rbac/memory/MemoryRole.java b/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/apache/archiva/redback/rbac/memory/MemoryRole.java
index c243af8..1eed3a0 100644
--- a/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/apache/archiva/redback/rbac/memory/MemoryRole.java
+++ b/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/apache/archiva/redback/rbac/memory/MemoryRole.java
@@ -61,6 +61,8 @@ public class MemoryRole
*/
private List<String> childRoleNames = new ArrayList<>( 0 );
+ private List<String> childRoleIds = new ArrayList<>( 0 );
+
/**
* Field permissions
*/
@@ -110,6 +112,20 @@ public class MemoryRole
return this.childRoleNames;
}
+
+
+ @Override
+ public void addChildRoleId( String id )
+ {
+ this.childRoleIds.add( id );
+ }
+
+ @Override
+ public List<String> getChildRoleIds( )
+ {
+ return this.childRoleIds;
+ }
+
@Override
public String getDescription()
{
@@ -199,6 +215,12 @@ public class MemoryRole
}
@Override
+ public void setChildRoleIds( List<String> ids )
+ {
+
+ }
+
+ @Override
public boolean isPermanent()
{
return permanent;
diff --git a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/DefaultRoleManager.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/DefaultRoleManager.java
index 9d68db6..9fbf5c9 100644
--- a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/DefaultRoleManager.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/DefaultRoleManager.java
@@ -21,6 +21,7 @@ package org.apache.archiva.redback.role;
import org.apache.archiva.redback.rbac.RBACManager;
import org.apache.archiva.redback.rbac.RbacManagerException;
+import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
import org.apache.archiva.redback.rbac.Role;
import org.apache.archiva.redback.rbac.UserAssignment;
import org.apache.archiva.redback.role.model.ModelApplication;
@@ -184,10 +185,10 @@ public class DefaultRoleManager
* resolving the ${resource} expression
*/
@Override
- public void createTemplatedRole( String templateId, String resource )
+ public String createTemplatedRole( String templateId, String resource )
throws RoleManagerException
{
- templateProcessor.create( blessedModel, templateId, resource );
+ return templateProcessor.create( blessedModel, templateId, resource );
}
/**
@@ -198,13 +199,10 @@ public class DefaultRoleManager
public void removeTemplatedRole( String templateId, String resource )
throws RoleManagerException
{
- ModelTemplate template = RoleModelUtils.getModelTemplate( blessedModel, templateId );
-
- String roleName = template.getNamePrefix() + template.getDelimiter() + resource;
-
+ String roleId = templateProcessor.getRoleId( templateId, resource );
try
{
- Role role = rbacManager.getRole( roleName );
+ Role role = rbacManager.getRoleById( roleId );
for ( UserAssignment assignment : rbacManager.getUserAssignmentsForRoles(
Arrays.asList( role.getName() ) ) )
@@ -213,10 +211,12 @@ public class DefaultRoleManager
rbacManager.saveUserAssignment( assignment );
}
+ } catch ( RbacObjectNotFoundException e) {
+ throw new RoleNotFoundException( e.getMessage( ), e );
}
catch ( RbacManagerException e )
{
- throw new RoleManagerException( "unable to remove role", e );
+ throw new RoleManagerException( "Unable to remove role", e );
}
templateProcessor.remove( blessedModel, templateId, resource );
@@ -229,11 +229,11 @@ public class DefaultRoleManager
* because of the use of the name as an identifier
*/
@Override
- public void moveTemplatedRole( String templateId, String oldResource, String newResource )
+ public String moveTemplatedRole( String templateId, String oldResource, String newResource )
throws RoleManagerException
{
// make the new role
- templateProcessor.create( blessedModel, templateId, newResource );
+ String roleId = templateProcessor.create( blessedModel, templateId, newResource );
ModelTemplate template = RoleModelUtils.getModelTemplate( blessedModel, templateId );
@@ -259,6 +259,7 @@ public class DefaultRoleManager
}
templateProcessor.remove( blessedModel, templateId, oldResource );
+ return roleId;
}
@Override
@@ -269,7 +270,7 @@ public class DefaultRoleManager
if ( modelRole == null )
{
- throw new RoleManagerException( "Unable to assign role: " + roleId + " does not exist." );
+ throw new RoleNotFoundException( "Unable to assign role: " + roleId + " does not exist." );
}
try
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleExistsException.java
similarity index 73%
copy from redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
copy to redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleExistsException.java
index 3faaf8c..0403cb3 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleExistsException.java
@@ -1,6 +1,4 @@
-package org.apache.archiva.redback.rest.api;
-
-/*
+package org.apache.archiva.redback.role;/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -21,9 +19,15 @@ package org.apache.archiva.redback.rest.api;
/**
* @author Martin Stockhammer <ma...@apache.org>
*/
-public interface Constants
+public class RoleExistsException extends RoleManagerException
{
- String DEFAULT_PAGE_LIMIT = "1000";
-
+ public RoleExistsException( String string )
+ {
+ super( string );
+ }
+ public RoleExistsException( String string, Throwable throwable )
+ {
+ super( string, throwable );
+ }
}
diff --git a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleManager.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleManager.java
index 7c727e8..7448a8f 100644
--- a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleManager.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleManager.java
@@ -53,7 +53,7 @@ public interface RoleManager
* @param resource
* @throws RoleManagerException
*/
- void createTemplatedRole( String templateId, String resource )
+ String createTemplatedRole( String templateId, String resource )
throws RoleManagerException;
/**
@@ -78,7 +78,7 @@ public interface RoleManager
* @param newResource the new resource name
* @throws RoleManagerException
*/
- void moveTemplatedRole( String templateId, String oldResource, String newResource )
+ String moveTemplatedRole( String templateId, String oldResource, String newResource )
throws RoleManagerException;
diff --git a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleNotFoundException.java
similarity index 73%
copy from redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
copy to redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleNotFoundException.java
index 3faaf8c..e29c14a 100644
--- a/redback-integrations/redback-rest/redback-rest-api/src/main/java/org/apache/archiva/redback/rest/api/Constants.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/RoleNotFoundException.java
@@ -1,6 +1,4 @@
-package org.apache.archiva.redback.rest.api;
-
-/*
+package org.apache.archiva.redback.role;/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -21,9 +19,15 @@ package org.apache.archiva.redback.rest.api;
/**
* @author Martin Stockhammer <ma...@apache.org>
*/
-public interface Constants
+public class RoleNotFoundException extends RoleManagerException
{
- String DEFAULT_PAGE_LIMIT = "1000";
-
+ public RoleNotFoundException( String string )
+ {
+ super( string );
+ }
+ public RoleNotFoundException( String string, Throwable throwable )
+ {
+ super( string, throwable );
+ }
}
diff --git a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/processor/DefaultRoleModelProcessor.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/processor/DefaultRoleModelProcessor.java
index e0b4b65..b39c0c7 100644
--- a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/processor/DefaultRoleModelProcessor.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/processor/DefaultRoleModelProcessor.java
@@ -216,6 +216,7 @@ public class DefaultRoleModelProcessor
{
ModelRole childRoleProfile = RoleModelUtils.getModelRole( model, childRoleId );
role.addChildRoleName( childRoleProfile.getName() );
+ role.addChildRoleId( childRoleProfile.getId() );
}
}
@@ -229,7 +230,7 @@ public class DefaultRoleModelProcessor
{
ModelRole parentModelRole = RoleModelUtils.getModelRole( model, parentRoleId );
Role parentRole = rbacManager.getRole( parentModelRole.getName() );
- parentRole.addChildRoleName( role.getName() );
+ parentRole.addChildRole( role );
rbacManager.saveRole( parentRole );
allRoleNames.add( parentRole.getName() );
}
diff --git a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/DefaultRoleTemplateProcessor.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/DefaultRoleTemplateProcessor.java
index 3c43333..f7533c1 100644
--- a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/DefaultRoleTemplateProcessor.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/DefaultRoleTemplateProcessor.java
@@ -25,7 +25,9 @@ import org.apache.archiva.redback.rbac.RbacManagerException;
import org.apache.archiva.redback.rbac.Resource;
import org.apache.archiva.redback.rbac.Role;
import org.apache.archiva.redback.rbac.RBACManager;
+import org.apache.archiva.redback.role.RoleExistsException;
import org.apache.archiva.redback.role.RoleManagerException;
+import org.apache.archiva.redback.role.RoleNotFoundException;
import org.apache.archiva.redback.role.model.ModelApplication;
import org.apache.archiva.redback.role.model.ModelOperation;
import org.apache.archiva.redback.role.model.ModelPermission;
@@ -60,8 +62,9 @@ public class DefaultRoleTemplateProcessor
@Named(value = "rbacManager#default")
private RBACManager rbacManager;
+ @Override
@SuppressWarnings("unchecked")
- public void create( RedbackRoleModel model, String templateId, String resource )
+ public String create( final RedbackRoleModel model, final String templateId, final String resource )
throws RoleManagerException
{
for ( ModelApplication application : model.getApplications() )
@@ -74,16 +77,16 @@ public class DefaultRoleTemplateProcessor
processResource( template, resource );
// templates are roles that have yet to be paired with a resource for creation
- processTemplate( model, template, resource );
+ return processTemplate( model, template, resource );
- return;
}
}
}
- throw new RoleManagerException( "unknown template '" + templateId + "'" );
+ throw new RoleNotFoundException( "unknown template '" + templateId + "'" );
}
+ @Override
@SuppressWarnings("unchecked")
public void remove( RedbackRoleModel model, String templateId, String resource )
throws RoleManagerException
@@ -106,11 +109,11 @@ public class DefaultRoleTemplateProcessor
private void removeTemplatedRole( RedbackRoleModel model, ModelTemplate template, String resource )
throws RoleManagerException
{
- String roleName = template.getNamePrefix() + template.getDelimiter() + resource;
+ String roleId = getRoleId( template.getId( ), resource );
try
{
- Role role = rbacManager.getRole( roleName );
+ Role role = rbacManager.getRoleById( roleId );
if ( !role.isPermanent() )
{
@@ -142,12 +145,12 @@ public class DefaultRoleTemplateProcessor
}
else
{
- throw new RoleManagerException( "unable to remove role, it is flagged permanent" );
+ throw new RoleManagerException( "Unable to remove role, it is flagged permanent" );
}
}
catch ( RbacManagerException e )
{
- throw new RoleManagerException( "unable to remove templated role: " + roleName, e );
+ throw new RoleManagerException( "Unable to remove templated role: " + roleId, e );
}
//catch ( RoleTemplateProcessorException e )
//{
@@ -173,12 +176,17 @@ public class DefaultRoleTemplateProcessor
}
}
+ @Override
+ public String getRoleId( String templateId, String resource) {
+ return templateId + "." + resource;
+ }
+
@SuppressWarnings("unchecked")
- private void processTemplate( RedbackRoleModel model, ModelTemplate template, String resource )
+ private String processTemplate( RedbackRoleModel model, ModelTemplate template, String resource )
throws RoleManagerException
{
final String templateName = template.getNamePrefix() + template.getDelimiter() + resource;
- final String roleId = template.getId( ) + "." + resource;
+ final String roleId = getRoleId( template.getId( ), resource );
List<Permission> permissions = processPermissions( model, template, resource );
@@ -190,7 +198,7 @@ public class DefaultRoleTemplateProcessor
}
catch ( RbacManagerException e )
{
- throw new RoleManagerException( e.getMessage(), e );
+ throw new RoleExistsException( e.getMessage(), e );
}
if ( !roleExists )
@@ -221,6 +229,7 @@ public class DefaultRoleTemplateProcessor
{
ModelRole childRoleProfile = RoleModelUtils.getModelRole( model, childRoleId );
role.addChildRoleName( childRoleProfile.getName() );
+ role.addChildRoleId( childRoleProfile.getId() );
}
}
@@ -246,12 +255,14 @@ public class DefaultRoleTemplateProcessor
if ( rbacManager.roleExists( childRoleName ) )
{
role.addChildRoleName( childRoleName );
+ role.addChildRoleId( getRoleId( childTemplateId, resource ) );
}
else
{
processTemplate( model, childModelTemplate, resource );
role.addChildRoleName( childRoleName );
+ role.addChildRoleId( getRoleId( childTemplateId, resource ) );
}
}
}
@@ -270,7 +281,7 @@ public class DefaultRoleTemplateProcessor
{
ModelRole parentModelRole = RoleModelUtils.getModelRole( model, parentRoleId );
Role parentRole = rbacManager.getRole( parentModelRole.getName() );
- parentRole.addChildRoleName( role.getName() );
+ parentRole.addChildRole( role );
rbacManager.saveRole( parentRole );
}
}
@@ -298,7 +309,7 @@ public class DefaultRoleTemplateProcessor
{
Role parentRole = rbacManager.getRole( parentRoleName );
- parentRole.addChildRoleName( role.getName() );
+ parentRole.addChildRole( role );
rbacManager.saveRole( parentRole );
}
else
@@ -307,7 +318,7 @@ public class DefaultRoleTemplateProcessor
Role parentRole = rbacManager.getRole( parentRoleName );
- parentRole.addChildRoleName( role.getName() );
+ parentRole.addChildRole( role );
rbacManager.saveRole( parentRole );
}
}
@@ -358,6 +369,7 @@ public class DefaultRoleTemplateProcessor
throw new RoleManagerException( "error updating role '" + templateName + "'", e );
}
}
+ return roleId;
}
@SuppressWarnings("unchecked")
diff --git a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/RoleTemplateProcessor.java b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/RoleTemplateProcessor.java
index 7f8e07d..e237a04 100644
--- a/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/RoleTemplateProcessor.java
+++ b/redback-rbac/redback-rbac-role-manager/src/main/java/org/apache/archiva/redback/role/template/RoleTemplateProcessor.java
@@ -30,9 +30,33 @@ import org.apache.archiva.redback.role.model.RedbackRoleModel;
public interface RoleTemplateProcessor
{
- void create( RedbackRoleModel model, String templateId, String resource )
+ /**
+ * Creates a role instance from a template for the given resource and returns the id of the new role.
+ * @param model the model
+ * @param templateId the template identifier
+ * @param resource the resource to which the role is applied
+ * @return the id of the role
+ * @throws RoleManagerException if the access to the backend datastore failed
+ */
+ String create( RedbackRoleModel model, String templateId, String resource )
throws RoleManagerException;
+ /**
+ * Removes the role instance that belongs to the template from the datastore
+ * @param model the model
+ * @param templateId the template identifier
+ * @param resource the resource to which the role is applied
+ * @throws RoleManagerException if the access to the backend datastore failed
+ */
void remove( RedbackRoleModel model, String templateId, String resource )
throws RoleManagerException;
+
+
+ /**
+ * Returns the role id that identifies the role that is a instance of the given template for the given resource.
+ * @param templateId the template identifier
+ * @param resource the resource
+ * @return the role identifier
+ */
+ String getRoleId( String templateId, String resource );
}
diff --git a/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerPerformanceTestCase.java b/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerPerformanceTestCase.java
index 11eacdd..7d1512f 100644
--- a/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerPerformanceTestCase.java
+++ b/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerPerformanceTestCase.java
@@ -169,6 +169,7 @@ public class AbstractRbacManagerPerformanceTestCase
Role devRole = getDeveloperRole();
Role devPlusRole = getSuperDeveloperRole();
devPlusRole.setChildRoleNames( Collections.singletonList( devRole.getName() ) );
+ devPlusRole.setChildRoleIds( Collections.singletonList( devRole.getId() ) );
devRole = manager.saveRole( devRole );
devPlusRole = manager.saveRole( devPlusRole );
@@ -197,6 +198,7 @@ public class AbstractRbacManagerPerformanceTestCase
username = "janet";
devPlusRole.setChildRoleNames( Collections.singletonList( devRole.getName() ) );
+ devPlusRole.setChildRoleIds( Collections.singletonList( devRole.getId() ) );
devRole = manager.saveRole( devRole );
manager.saveRole( devPlusRole );
diff --git a/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerTestCase.java b/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerTestCase.java
index 5ec4cc5..bca655e 100644
--- a/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerTestCase.java
+++ b/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/AbstractRbacManagerTestCase.java
@@ -91,7 +91,7 @@ public abstract class AbstractRbacManagerTestCase
private Role getAdminRole()
throws RbacManagerException
{
- Role role = rbacManager.createRole( "ADMIN" );
+ Role role = rbacManager.createRole( "admin", "ADMIN" );
role.setAssignable( false );
Permission perm = rbacManager.createPermission( "EDIT_ANY_USER", "EDIT", "User:*" );
@@ -375,6 +375,7 @@ public abstract class AbstractRbacManagerTestCase
manager.saveRole( projectRole );
develRole.addChildRoleName( projectRoleName );
+ develRole.addChildRoleId( projectRole.getId() );
manager.saveRole( develRole );
@@ -428,7 +429,7 @@ public abstract class AbstractRbacManagerTestCase
Role adminRole = getAdminRole();
- adminRole.addChildRoleName( developerRole.getName() );
+ adminRole.addChildRole( developerRole );
adminRole = manager.saveRole( adminRole );
@@ -631,6 +632,7 @@ public abstract class AbstractRbacManagerTestCase
Role devRole = getDeveloperRole();
Role devPlusRole = getSuperDeveloperRole();
devPlusRole.setChildRoleNames( Collections.singletonList( devRole.getName() ) );
+ devPlusRole.setChildRoleIds( Collections.singletonList( devRole.getId() ) );
manager.saveRole( devRole );
manager.saveRole( devPlusRole );
diff --git a/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/utils/RBACDefaults.java b/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/utils/RBACDefaults.java
index 16c85af..a451485 100644
--- a/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/utils/RBACDefaults.java
+++ b/redback-rbac/redback-rbac-tests/src/main/java/org/apache/archiva/redback/tests/utils/RBACDefaults.java
@@ -159,6 +159,7 @@ public class RBACDefaults
{
Role admin = manager.createRole( "System Administrator" );
admin.addChildRoleName( "User Administrator" );
+ admin.addChildRoleId( "user-administrator" );
admin.addPermission( manager.getPermission( "Edit Configuration" ) );
admin.addPermission( manager.getPermission( "Run Indexer" ) );
admin.addPermission( manager.getPermission( "Add Repository" ) );
@@ -171,6 +172,7 @@ public class RBACDefaults
{
Role developer = manager.createRole( "Trusted Developer" );
developer.addChildRoleName( "System Administrator" );
+ developer.addChildRoleId( "system-administrator" );
developer.addPermission( manager.getPermission( "Run Indexer" ) );
developer.setAssignable( true );
manager.saveRole( developer );
@@ -180,6 +182,7 @@ public class RBACDefaults
{
Role developer = manager.createRole( "Developer" );
developer.addChildRoleName( "Trusted Developer" );
+ developer.addChildRoleId( "trusted-developer" );
developer.addPermission( manager.getPermission( "Run Indexer" ) );
developer.setAssignable( true );
manager.saveRole( developer );