mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
projects: Role based users in Projects (#4128)
Enabling Role Based users in projects Primate PR related to the FR: apache/cloudstack-primate#382 Doc PR: https://github.com/apache/cloudstack-documentation/pull/145 Co-authored-by: Pearl Dsilva <pearl.dsilva@shapeblue.com> Co-authored-by: Suresh Kumar Anaparti <suresh.anaparti@shapeblue.com>
This commit is contained in:
parent
3adee270c7
commit
c578004fe5
@ -22,6 +22,10 @@ import java.util.Map;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.annotation.Annotation;
|
||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.config.Configuration;
|
||||
import org.apache.cloudstack.ha.HAConfig;
|
||||
import org.apache.cloudstack.usage.Usage;
|
||||
@ -76,10 +80,6 @@ import com.cloud.user.User;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
|
||||
public class EventTypes {
|
||||
|
||||
@ -190,6 +190,14 @@ public class EventTypes {
|
||||
public static final String EVENT_ROLE_PERMISSION_UPDATE = "ROLE.PERMISSION.UPDATE";
|
||||
public static final String EVENT_ROLE_PERMISSION_DELETE = "ROLE.PERMISSION.DELETE";
|
||||
|
||||
// Project Role events
|
||||
public static final String EVENT_PROJECT_ROLE_CREATE = "PROJECT.ROLE.CREATE";
|
||||
public static final String EVENT_PROJECT_ROLE_UPDATE = "PROJECT.ROLE.UPDATE";
|
||||
public static final String EVENT_PROJECT_ROLE_DELETE = "PROJECT.ROLE.DELETE";
|
||||
public static final String EVENT_PROJECT_ROLE_PERMISSION_CREATE = "PROJECT.ROLE.PERMISSION.CREATE";
|
||||
public static final String EVENT_PROJECT_ROLE_PERMISSION_UPDATE = "PROJECT.ROLE.PERMISSION.UPDATE";
|
||||
public static final String EVENT_PROJECT_ROLE_PERMISSION_DELETE = "PROJECT.ROLE.PERMISSION.DELETE";
|
||||
|
||||
// CA events
|
||||
public static final String EVENT_CA_CERTIFICATE_ISSUE = "CA.CERTIFICATE.ISSUE";
|
||||
public static final String EVENT_CA_CERTIFICATE_REVOKE = "CA.CERTIFICATE.REVOKE";
|
||||
@ -399,9 +407,11 @@ public class EventTypes {
|
||||
public static final String EVENT_PROJECT_ACTIVATE = "PROJECT.ACTIVATE";
|
||||
public static final String EVENT_PROJECT_SUSPEND = "PROJECT.SUSPEND";
|
||||
public static final String EVENT_PROJECT_ACCOUNT_ADD = "PROJECT.ACCOUNT.ADD";
|
||||
public static final String EVENT_PROJECT_USER_ADD = "PROJECT.USER.ADD";
|
||||
public static final String EVENT_PROJECT_INVITATION_UPDATE = "PROJECT.INVITATION.UPDATE";
|
||||
public static final String EVENT_PROJECT_INVITATION_REMOVE = "PROJECT.INVITATION.REMOVE";
|
||||
public static final String EVENT_PROJECT_ACCOUNT_REMOVE = "PROJECT.ACCOUNT.REMOVE";
|
||||
public static final String EVENT_PROJECT_USER_REMOVE = "PROJECT.USER.REMOVE";
|
||||
|
||||
// Network as a Service
|
||||
public static final String EVENT_NETWORK_ELEMENT_CONFIGURE = "NETWORK.ELEMENT.CONFIGURE";
|
||||
|
||||
@ -23,8 +23,12 @@ public interface ProjectAccount {
|
||||
|
||||
long getAccountId();
|
||||
|
||||
Long getUserId();
|
||||
|
||||
long getProjectId();
|
||||
|
||||
Long getProjectRoleId();
|
||||
|
||||
Role getAccountRole();
|
||||
|
||||
long getProjectAccountId();
|
||||
|
||||
@ -41,4 +41,10 @@ public interface ProjectInvitation extends ControlledEntity, Identity, InternalI
|
||||
|
||||
Long getInDomainId();
|
||||
|
||||
ProjectAccount.Role getAccountRole();
|
||||
|
||||
Long getForUserId();
|
||||
|
||||
Long getProjectRoleId();
|
||||
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package com.cloud.projects;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
@ -34,10 +36,17 @@ public interface ProjectService {
|
||||
* - account name of the project owner
|
||||
* @param domainId
|
||||
* - domainid of the project owner
|
||||
*
|
||||
* @param userId
|
||||
* - id of the user to be made as project owner
|
||||
*
|
||||
* @param accountId
|
||||
* - id of the account to which the user belongs
|
||||
*
|
||||
* @return the project if created successfully, null otherwise
|
||||
* @throws ResourceAllocationException
|
||||
*/
|
||||
Project createProject(String name, String displayText, String accountName, Long domainId) throws ResourceAllocationException;
|
||||
Project createProject(String name, String displayText, String accountName, Long domainId, Long userId, Long accountId) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Deletes a project
|
||||
@ -57,10 +66,12 @@ public interface ProjectService {
|
||||
*/
|
||||
Project getProject(long id);
|
||||
|
||||
ProjectAccount assignAccountToProject(Project project, long accountId, Role accountRole);
|
||||
ProjectAccount assignAccountToProject(Project project, long accountId, Role accountRole, Long userId, Long projectRoleId);
|
||||
|
||||
Account getProjectOwner(long projectId);
|
||||
|
||||
List<Long> getProjectOwners(long projectId);
|
||||
|
||||
boolean unassignAccountFromProject(long projectId, long accountId);
|
||||
|
||||
Project findByProjectAccountId(long projectAccountId);
|
||||
@ -69,11 +80,15 @@ public interface ProjectService {
|
||||
|
||||
Project updateProject(long id, String displayText, String newOwnerName) throws ResourceAllocationException;
|
||||
|
||||
boolean addAccountToProject(long projectId, String accountName, String email);
|
||||
Project updateProject(long id, String displayText, String newOwnerName, Long userId, Role newRole) throws ResourceAllocationException;
|
||||
|
||||
boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType);
|
||||
|
||||
boolean deleteAccountFromProject(long projectId, String accountName);
|
||||
|
||||
boolean updateInvitation(long projectId, String accountName, String token, boolean accept);
|
||||
boolean deleteUserFromProject(long projectId, long userId);
|
||||
|
||||
boolean updateInvitation(long projectId, String accountName, Long userId, String token, boolean accept);
|
||||
|
||||
Project activateProject(long projectId);
|
||||
|
||||
@ -84,4 +99,7 @@ public interface ProjectService {
|
||||
boolean deleteProjectInvitation(long invitationId);
|
||||
|
||||
Project findByProjectAccountIdIncludingRemoved(long projectAccountId);
|
||||
|
||||
boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole);
|
||||
|
||||
}
|
||||
|
||||
26
api/src/main/java/org/apache/cloudstack/acl/ProjectRole.java
Normal file
26
api/src/main/java/org/apache/cloudstack/acl/ProjectRole.java
Normal file
@ -0,0 +1,26 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface ProjectRole extends RoleEntity, InternalIdentity, Identity {
|
||||
|
||||
Long getProjectId();
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
public interface ProjectRolePermission extends RolePermissionEntity {
|
||||
long getProjectRoleId();
|
||||
long getProjectId();
|
||||
long getSortOrder();
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.acl.project.CreateProjectRolePermissionCmd;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
|
||||
public interface ProjectRoleService {
|
||||
/**
|
||||
* Creates a Project role in a Project to be mapped to a user/ account (all users of an account)
|
||||
* @param projectId ID of the project where the project role is to be created
|
||||
* @param name Name of the project role
|
||||
* @param description description provided for the project role
|
||||
* @return the Instance of the project role created
|
||||
*/
|
||||
ProjectRole createProjectRole(Long projectId, String name, String description);
|
||||
|
||||
/**
|
||||
* Updates a Project role created
|
||||
* @param role Project role reference to be updated
|
||||
* @param projectId ID of the project where the Project role exists
|
||||
* @param name new name to be given to the project role
|
||||
* @param description description for the project role
|
||||
* @return the updated instance of the project role
|
||||
*/
|
||||
ProjectRole updateProjectRole(ProjectRole role, Long projectId, String name, String description);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param projectId ID of the project in which the project role is to be searched for
|
||||
* @param roleName name/ part of a project role name
|
||||
* @return List of Project roles matching the given name in the project
|
||||
*/
|
||||
List<ProjectRole> findProjectRolesByName(Long projectId, String roleName);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param role Project role to be deleted
|
||||
* @param projectId ID of the project where the role is present
|
||||
* @return success/failure of the delete operation
|
||||
*/
|
||||
boolean deleteProjectRole(ProjectRole role, Long projectId);
|
||||
|
||||
/**
|
||||
* Determines if Dynamic Roles feature is enabled , if it isn't then the project roles will not be applied
|
||||
*/
|
||||
boolean isEnabled();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param roleId Project role ID which needs to be found
|
||||
* @param projectId ID of the project where the role is to be found
|
||||
* @return the corresponding project role
|
||||
*/
|
||||
ProjectRole findProjectRole(Long roleId, Long projectId);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param projectId ID of the project whosr project roles are to be listed
|
||||
* @return List of all available project roles
|
||||
*/
|
||||
List<ProjectRole> findProjectRoles(Long projectId);
|
||||
|
||||
/**
|
||||
* Creates a project role permission to be mapped to a project role.
|
||||
* All accounts/users mapped to this project role will impose restrictions on API access
|
||||
* to users based on the project role. This is to further limit restrictions on users in projects
|
||||
*/
|
||||
ProjectRolePermission createProjectRolePermission(CreateProjectRolePermissionCmd cmd);
|
||||
|
||||
/**
|
||||
* Updates the order of the project role permission
|
||||
* @param projectId ID of the project where the project role permission exists
|
||||
* @param projectRole project role to which the permission is mapped to
|
||||
* @param rolePermissionsOrder re-arranged order of permissions
|
||||
* @return success/failure of operation
|
||||
*/
|
||||
boolean updateProjectRolePermission(Long projectId, ProjectRole projectRole, List<ProjectRolePermission> rolePermissionsOrder);
|
||||
|
||||
/**
|
||||
*
|
||||
* Updates the permission of the project role permission
|
||||
*/
|
||||
boolean updateProjectRolePermission(Long projectId, ProjectRole projectRole, ProjectRolePermission projectRolePermission, Permission newPermission);
|
||||
|
||||
/**
|
||||
* Finds the project role permission for the given ID
|
||||
*/
|
||||
ProjectRolePermission findProjectRolePermission(final Long projRolePermissionId);
|
||||
|
||||
/**
|
||||
* deletes the given project role
|
||||
*/
|
||||
boolean deleteProjectRolePermission(ProjectRolePermission projectRolePermission);
|
||||
|
||||
/**
|
||||
* returns list of all project role permissions mapped to the requested project role
|
||||
*/
|
||||
List<ProjectRolePermission> findAllProjectRolePermissions(Long projectId, Long projectRoleId);
|
||||
|
||||
}
|
||||
@ -20,9 +20,7 @@ package org.apache.cloudstack.acl;
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface Role extends InternalIdentity, Identity {
|
||||
String getName();
|
||||
public interface Role extends RoleEntity, InternalIdentity, Identity {
|
||||
RoleType getRoleType();
|
||||
String getDescription();
|
||||
boolean isDefault();
|
||||
}
|
||||
|
||||
26
api/src/main/java/org/apache/cloudstack/acl/RoleEntity.java
Normal file
26
api/src/main/java/org/apache/cloudstack/acl/RoleEntity.java
Normal file
@ -0,0 +1,26 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface RoleEntity extends InternalIdentity, Identity {
|
||||
String getName();
|
||||
String getDescription();
|
||||
}
|
||||
@ -17,15 +17,7 @@
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface RolePermission extends InternalIdentity, Identity {
|
||||
enum Permission {ALLOW, DENY}
|
||||
|
||||
public interface RolePermission extends RolePermissionEntity {
|
||||
long getRoleId();
|
||||
Rule getRule();
|
||||
Permission getPermission();
|
||||
String getDescription();
|
||||
long getSortOrder();
|
||||
}
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface RolePermissionEntity extends InternalIdentity, Identity {
|
||||
public enum Permission {
|
||||
ALLOW, DENY
|
||||
}
|
||||
Rule getRule();
|
||||
Permission getPermission();
|
||||
String getDescription();
|
||||
}
|
||||
@ -22,7 +22,7 @@ import java.util.Map;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
import org.apache.cloudstack.acl.RolePermission.Permission;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
public interface RoleService {
|
||||
|
||||
@ -348,6 +348,8 @@ public class ApiConstants {
|
||||
public static final String STORAGE_POLICY = "storagepolicy";
|
||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
||||
public static final String OWNER = "owner";
|
||||
public static final String SWAP_OWNER = "swapowner";
|
||||
public static final String SYSTEM_VM_TYPE = "systemvmtype";
|
||||
public static final String TAGS = "tags";
|
||||
public static final String TARGET_IQN = "targetiqn";
|
||||
@ -474,12 +476,15 @@ public class ApiConstants {
|
||||
public static final String PROJECT = "project";
|
||||
public static final String ROLE = "role";
|
||||
public static final String ROLE_ID = "roleid";
|
||||
public static final String PROJECT_ROLE_ID = "projectroleid";
|
||||
public static final String PROJECT_ROLE_NAME = "projectrolename";
|
||||
public static final String ROLE_TYPE = "roletype";
|
||||
public static final String ROLE_NAME = "rolename";
|
||||
public static final String PERMISSION = "permission";
|
||||
public static final String RULE = "rule";
|
||||
public static final String RULES = "rules";
|
||||
public static final String RULE_ID = "ruleid";
|
||||
public static final String PROJECT_ROLE_PERMISSION_ID = "projectrolepermissionid";
|
||||
public static final String RULE_ORDER = "ruleorder";
|
||||
public static final String USER = "user";
|
||||
public static final String ACTIVE_ONLY = "activeonly";
|
||||
|
||||
@ -39,7 +39,7 @@ public interface ApiServerService {
|
||||
|
||||
public String getSerializedApiError(ServerApiException ex, Map<String, Object[]> apiCommandParams, String responseType);
|
||||
|
||||
public String handleRequest(Map params, String responseType, StringBuilder auditTrailSb) throws ServerApiException;
|
||||
public String handleRequest(Map<String, Object[]> params, String responseType, StringBuilder auditTrailSb) throws ServerApiException;
|
||||
|
||||
public Class<?> getCmdClass(String cmdName);
|
||||
|
||||
|
||||
@ -17,6 +17,32 @@
|
||||
|
||||
package org.apache.cloudstack.api;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRoleService;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
import org.apache.cloudstack.alert.AlertService;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
||||
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
|
||||
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
|
||||
import org.apache.cloudstack.query.QueryService;
|
||||
import org.apache.cloudstack.usage.UsageService;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.ConfigurationService;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
@ -58,29 +84,6 @@ import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.UUIDManager;
|
||||
import com.cloud.vm.UserVmService;
|
||||
import com.cloud.vm.snapshot.VMSnapshotService;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
import org.apache.cloudstack.alert.AlertService;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
|
||||
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
|
||||
import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
|
||||
import org.apache.cloudstack.query.QueryService;
|
||||
import org.apache.cloudstack.usage.UsageService;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class BaseCmd {
|
||||
private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName());
|
||||
@ -112,6 +115,8 @@ public abstract class BaseCmd {
|
||||
@Inject
|
||||
public RoleService roleService;
|
||||
@Inject
|
||||
public ProjectRoleService projRoleService;
|
||||
@Inject
|
||||
public UserVmService _userVmService;
|
||||
@Inject
|
||||
public ManagementService _mgr;
|
||||
@ -264,6 +269,10 @@ public abstract class BaseCmd {
|
||||
*/
|
||||
public abstract long getEntityOwnerId();
|
||||
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getResponseObject() {
|
||||
return _responseObject;
|
||||
}
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl;
|
||||
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.acl.Rule;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
public abstract class BaseRolePermissionCmd extends BaseCmd {
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.RULE, type = CommandType.STRING, required = true, description = "The API name or wildcard rule such as list*",
|
||||
validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private String rule;
|
||||
|
||||
@Parameter(name = ApiConstants.PERMISSION, type = CommandType.STRING, required = true, description = "The rule permission, allow or deny. Default: deny.")
|
||||
private String permission;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "The description of the role permission")
|
||||
private String description;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Rule getRule() {
|
||||
return new Rule(rule);
|
||||
}
|
||||
|
||||
public Permission getPermission() {
|
||||
if (Strings.isNullOrEmpty(permission)) {
|
||||
return null;
|
||||
}
|
||||
return Permission.valueOf(permission.toUpperCase());
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
}
|
||||
@ -17,28 +17,27 @@
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.Rule;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.response.RolePermissionResponse;
|
||||
import org.apache.cloudstack.api.response.RoleResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = CreateRolePermissionCmd.APINAME, description = "Adds a API permission to a role", responseObject = RolePermissionResponse.class,
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = CreateRolePermissionCmd.APINAME, description = "Adds an API permission to a role", responseObject = RolePermissionResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
since = "4.9.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class CreateRolePermissionCmd extends BaseCmd {
|
||||
public class CreateRolePermissionCmd extends BaseRolePermissionCmd {
|
||||
public static final String APINAME = "createRolePermission";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
@ -49,16 +48,6 @@ public class CreateRolePermissionCmd extends BaseCmd {
|
||||
description = "ID of the role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long roleId;
|
||||
|
||||
@Parameter(name = ApiConstants.RULE, type = CommandType.STRING, required = true, description = "The API name or wildcard rule such as list*",
|
||||
validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private String rule;
|
||||
|
||||
@Parameter(name = ApiConstants.PERMISSION, type = CommandType.STRING, required = true, description = "The rule permission, allow or deny. Default: deny.")
|
||||
private String permission;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "The description of the role permission")
|
||||
private String description;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -67,21 +56,6 @@ public class CreateRolePermissionCmd extends BaseCmd {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public Rule getRule() {
|
||||
return new Rule(rule);
|
||||
}
|
||||
|
||||
public RolePermission.Permission getPermission() {
|
||||
if (Strings.isNullOrEmpty(permission)) {
|
||||
return null;
|
||||
}
|
||||
return RolePermission.Permission.valueOf(permission.toUpperCase());
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -17,10 +17,12 @@
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.acl.RolePermission.Permission;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
@ -34,8 +36,7 @@ import org.apache.cloudstack.api.response.RoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = UpdateRolePermissionCmd.APINAME, description = "Updates a role permission order", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = CreateProjectRoleCmd.APINAME, description = "Creates a Project role", responseObject = ProjectRoleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User}, since = "4.15.0")
|
||||
public class CreateProjectRoleCmd extends ProjectRoleCmd {
|
||||
public static final String APINAME = "createProjectRole";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING, required = true,
|
||||
description = "creates a project role with this unique name", validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private String projectRoleName;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getProjectRoleName() {
|
||||
return projectRoleName;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails("Role: " + getProjectRoleName() + ", description: " + getProjectRoleDescription());
|
||||
ProjectRole projectRole = projRoleService.createProjectRole(getProjectId(), getProjectRoleName(), getProjectRoleDescription());
|
||||
if (projectRole == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create project role");
|
||||
}
|
||||
setupProjectRoleResponse(projectRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.admin.acl.BaseRolePermissionCmd;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRolePermissionResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = CreateProjectRolePermissionCmd.APINAME, description = "Adds API permissions to a project role", responseObject = ProjectRolePermissionResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {
|
||||
RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, since = "4.15.0")
|
||||
public class CreateProjectRolePermissionCmd extends BaseRolePermissionCmd {
|
||||
public static final String APINAME = "createProjectRolePermission";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = CommandType.UUID, required = true, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the project role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectRoleId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, required = true, entityType = ProjectResponse.class,
|
||||
description = "ID of project where project role permission is to be created", validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private Long projectId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRole projectRole = projRoleService.findProjectRole(getProjectRoleId(), getProjectId());
|
||||
if (projectRole == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid project role ID provided");
|
||||
}
|
||||
CallContext.current().setEventDetails("Project Role ID: " + projectRole.getId() + ", Rule:" + getRule() + ", Permission: " + getPermission() + ", Description: " + getDescription());
|
||||
final ProjectRolePermission projectRolePermission = projRoleService.createProjectRolePermission(this);
|
||||
if (projectRolePermission == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create project role permission");
|
||||
}
|
||||
setupResponse(projectRolePermission, projectRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
|
||||
private void setupResponse(final ProjectRolePermission rolePermission, final ProjectRole role) {
|
||||
final ProjectRolePermissionResponse response = new ProjectRolePermissionResponse();
|
||||
response.setId(rolePermission.getUuid());
|
||||
response.setProjectId(_projectService.getProject(rolePermission.getProjectId()).getUuid());
|
||||
response.setProjectRoleId(role.getUuid());
|
||||
response.setRule(rolePermission.getRule());
|
||||
response.setRulePermission(rolePermission.getPermission());
|
||||
response.setDescription(rolePermission.getDescription());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("projectrolepermission");
|
||||
setResponseObject(response);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = DeleteProjectRoleCmd.APINAME, description = "Delete Project roles in CloudStack", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.15.0", authorized = {
|
||||
RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class DeleteProjectRoleCmd extends BaseCmd {
|
||||
public static final String APINAME = "deleteProjectRole" ;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the project role to be deleted", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ProjectResponse.class,
|
||||
description = "ID of the project from where the role is to be deleted", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectId;
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getProjectId() { return projectId; }
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRole role = projRoleService.findProjectRole(getId(), getProjectId());
|
||||
if (role == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find project role with provided id");
|
||||
}
|
||||
CallContext.current().setEventDetails("Deleting Project Role with id: " + role.getId());
|
||||
boolean result = projRoleService.deleteProjectRole(role, getProjectId());
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setSuccess(result);
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRolePermissionResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = DeleteProjectRolePermissionCmd.APINAME, description = "Deletes a project role permission in the project", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {
|
||||
RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, since = "4.15.0")
|
||||
public class DeleteProjectRolePermissionCmd extends BaseCmd {
|
||||
public static final String APINAME = "deleteProjectRolePermission";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ProjectResponse.class,
|
||||
description = "ID of the project where the project role permission is to be deleted", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, required = true, entityType = ProjectRolePermissionResponse.class,
|
||||
description = "ID of the project role permission to be deleted", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectRolePermissionId;
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Long getProjectRolePermissionId() {
|
||||
return projectRolePermissionId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRolePermission rolePermission = projRoleService.findProjectRolePermission(getProjectRolePermissionId());
|
||||
if (rolePermission == null || rolePermission.getProjectId() != getProjectId()) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role permission id provided for the project");
|
||||
}
|
||||
CallContext.current().setEventDetails("Deleting Project Role permission with id: " + rolePermission.getId());
|
||||
boolean result = projRoleService.deleteProjectRolePermission(rolePermission);
|
||||
SuccessResponse response = new SuccessResponse();
|
||||
response.setSuccess(result);
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRolePermissionResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = ListProjectRolePermissionsCmd.APINAME, description = "Lists a project's project role permissions", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {
|
||||
RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, since = "4.15.0")
|
||||
public class ListProjectRolePermissionsCmd extends BaseCmd {
|
||||
public static final String APINAME = "listProjectRolePermissions";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, required = true, description = "ID of the project")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = CommandType.UUID, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the project role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectRoleId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<ProjectRolePermission> projectRolePermissions = projRoleService.findAllProjectRolePermissions(getProjectId(), getProjectRoleId());
|
||||
final ProjectRole projectRole = projRoleService.findProjectRole(getProjectRoleId(), getProjectId());
|
||||
final ListResponse<ProjectRolePermissionResponse> response = new ListResponse<>();
|
||||
final List<ProjectRolePermissionResponse> rolePermissionResponses = new ArrayList<>();
|
||||
for (final ProjectRolePermission rolePermission : projectRolePermissions) {
|
||||
ProjectRole role = projectRole;
|
||||
if (role == null) {
|
||||
role = projRoleService.findProjectRole(rolePermission.getProjectRoleId(), rolePermission.getProjectId());
|
||||
}
|
||||
rolePermissionResponses.add(setupResponse(role, rolePermission));
|
||||
}
|
||||
response.setResponses(rolePermissionResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
private ProjectRolePermissionResponse setupResponse(ProjectRole role, ProjectRolePermission rolePermission) {
|
||||
final ProjectRolePermissionResponse rolePermissionResponse = new ProjectRolePermissionResponse();
|
||||
rolePermissionResponse.setProjectId(_projectService.getProject(rolePermission.getProjectId()).getUuid());
|
||||
rolePermissionResponse.setProjectRoleId(role.getUuid());
|
||||
rolePermissionResponse.setProjectRoleName(role.getName());
|
||||
rolePermissionResponse.setId(rolePermission.getUuid());
|
||||
rolePermissionResponse.setRule(rolePermission.getRule());
|
||||
rolePermissionResponse.setRulePermission(rolePermission.getPermission());
|
||||
rolePermissionResponse.setDescription(rolePermission.getDescription());
|
||||
rolePermissionResponse.setObjectName("projectrolepermission");
|
||||
return rolePermissionResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@APICommand(name = ListProjectRolesCmd.APINAME, description = "Lists Project roles in CloudStack", responseObject = ProjectRoleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, since = "4.15.0", authorized = {
|
||||
RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
|
||||
public class ListProjectRolesCmd extends BaseCmd {
|
||||
public static final String APINAME = "listProjectRoles";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = CommandType.UUID, entityType = ProjectRoleResponse.class, description = "List project role by project role ID.")
|
||||
private Long projectRoleId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, required = true, description = "List project role by project ID.")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "List project role by project role name.")
|
||||
private String roleName;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public Long getProjectRoleId() { return projectRoleId; }
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public String getRoleName() {
|
||||
return roleName;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<ProjectRole> projectRoles;
|
||||
if (getProjectId() != null && getProjectRoleId() != null) {
|
||||
projectRoles = Collections.singletonList(projRoleService.findProjectRole(getProjectRoleId(), getProjectId()));
|
||||
} else if (StringUtils.isNotBlank(getRoleName())) {
|
||||
projectRoles = projRoleService.findProjectRolesByName(getProjectId(), getRoleName());
|
||||
} else {
|
||||
projectRoles = projRoleService.findProjectRoles(getProjectId());
|
||||
}
|
||||
final ListResponse<ProjectRoleResponse> response = new ListResponse<>();
|
||||
final List<ProjectRoleResponse> roleResponses = new ArrayList<>();
|
||||
for (ProjectRole role : projectRoles) {
|
||||
if (role == null) {
|
||||
continue;
|
||||
}
|
||||
roleResponses.add(setupProjectRoleResponse(role));
|
||||
}
|
||||
response.setResponses(roleResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
private ProjectRoleResponse setupProjectRoleResponse(final ProjectRole role) {
|
||||
final ProjectRoleResponse response = new ProjectRoleResponse();
|
||||
response.setId(role.getUuid());
|
||||
response.setProjectId(_projectService.getProject(role.getProjectId()).getUuid());
|
||||
response.setRoleName(role.getName());
|
||||
response.setDescription(role.getDescription());
|
||||
response.setObjectName("projectrole");
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
|
||||
public abstract class ProjectRoleCmd extends BaseCmd {
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, required = true, entityType = ProjectResponse.class,
|
||||
description = "ID of project where role is being created", validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = BaseCmd.CommandType.STRING, description = "The description of the Project role")
|
||||
private String projectRoleDescription;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public String getProjectRoleDescription() {
|
||||
return projectRoleDescription;
|
||||
}
|
||||
|
||||
protected void setupProjectRoleResponse(final ProjectRole role) {
|
||||
final ProjectRoleResponse response = new ProjectRoleResponse();
|
||||
response.setId(role.getUuid());
|
||||
response.setProjectId(_projectService.getProject(role.getProjectId()).getUuid());
|
||||
response.setRoleName(role.getName());
|
||||
response.setDescription(role.getDescription());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("projectrole");
|
||||
setResponseObject(response);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
|
||||
@APICommand(name = UpdateProjectRoleCmd.APINAME, description = "Creates a Project role", responseObject = ProjectRoleResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User}, since = "4.15.0")
|
||||
public class UpdateProjectRoleCmd extends ProjectRoleCmd {
|
||||
public static final String APINAME = "updateProjectRole";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API Parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, required = true, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the Project role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = BaseCmd.CommandType.STRING,
|
||||
description = "creates a project role with this unique name", validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private String projectRoleName;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// Accessors //////////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getProjectRoleName() {
|
||||
return projectRoleName;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API Implementation /////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRole role = projRoleService.findProjectRole(getId(), getProjectId());
|
||||
if (role == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid project role id provided");
|
||||
}
|
||||
role = projRoleService.updateProjectRole(role, getProjectId(), getProjectRoleName(), getProjectRoleDescription());
|
||||
setupProjectRoleResponse(role);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,163 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.acl.project;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRolePermissionResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
@APICommand(name = UpdateProjectRolePermissionCmd.APINAME, description = "Updates a project role permission and/or order", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {
|
||||
RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User}, since = "4.15.0")
|
||||
public class UpdateProjectRolePermissionCmd extends BaseCmd {
|
||||
public static final String APINAME = "updateProjectRolePermission";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = CommandType.UUID, required = true, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the project role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectRoleId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, required = true, entityType = ProjectResponse.class,
|
||||
description = "ID of project where project role permission is to be updated", validations = {ApiArgValidator.NotNullOrEmpty})
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.RULE_ORDER, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = ProjectRolePermissionResponse.class,
|
||||
description = "The parent role permission uuid, use 0 to move this rule at the top of the list")
|
||||
private List<Long> projectRulePermissionOrder;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_PERMISSION_ID, type = CommandType.UUID, entityType = ProjectRolePermissionResponse.class,
|
||||
description = "Project Role permission rule id")
|
||||
private Long projectRuleId;
|
||||
|
||||
@Parameter(name = ApiConstants.PERMISSION, type = CommandType.STRING,
|
||||
description = "Rule permission, can be: allow or deny")
|
||||
private String projectRolePermission;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public List<Long> getProjectRulePermissionOrder() {
|
||||
return projectRulePermissionOrder;
|
||||
}
|
||||
|
||||
public Long getProjectRuleId() {
|
||||
return projectRuleId;
|
||||
}
|
||||
|
||||
public Permission getProjectRolePermission() {
|
||||
if (this.projectRolePermission == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!EnumUtils.isValidEnum(Permission.class, projectRolePermission.toUpperCase())) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Values for permission parameter should be: allow or deny");
|
||||
}
|
||||
|
||||
return Permission.valueOf(projectRolePermission.toUpperCase());
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// API Implementation //////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRole projectRole = projRoleService.findProjectRole(getProjectRoleId(), getProjectId());
|
||||
boolean result = false;
|
||||
if (projectRole == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid role id provided");
|
||||
}
|
||||
if (getProjectRulePermissionOrder() != null) {
|
||||
if (getProjectRuleId() != null || getProjectRolePermission() != null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
|
||||
}
|
||||
CallContext.current().setEventDetails("Reordering permissions for role id: " + projectRole.getId());
|
||||
result = updateProjectRolePermissionOrder(projectRole);
|
||||
|
||||
} else if (getProjectRuleId() != null || getProjectRolePermission() != null ) {
|
||||
if (getProjectRulePermissionOrder() != null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Parameters permission and ruleid must be mutually exclusive with ruleorder");
|
||||
}
|
||||
ProjectRolePermission rolePermission = getValidProjectRolePermission();
|
||||
CallContext.current().setEventDetails("Updating project role permission for rule id: " + getProjectRuleId() + " to: " + getProjectRolePermission().toString());
|
||||
result = projRoleService.updateProjectRolePermission(projectId, projectRole, rolePermission, getProjectRolePermission());
|
||||
}
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setSuccess(result);
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
private ProjectRolePermission getValidProjectRolePermission() {
|
||||
ProjectRolePermission rolePermission = projRoleService.findProjectRolePermission(getProjectRuleId());
|
||||
if (rolePermission == null || rolePermission.getProjectId() != getProjectId()) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Role permission doesn't exist in the project, probably because of invalid rule id");
|
||||
}
|
||||
return rolePermission;
|
||||
}
|
||||
|
||||
private boolean updateProjectRolePermissionOrder(ProjectRole projectRole) {
|
||||
final List<ProjectRolePermission> rolePermissionsOrder = new ArrayList<>();
|
||||
for (Long rolePermissionId : getProjectRulePermissionOrder()) {
|
||||
final ProjectRolePermission rolePermission = projRoleService.findProjectRolePermission(rolePermissionId);
|
||||
if (rolePermission == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Provided project role permission(s) do not exist");
|
||||
}
|
||||
rolePermissionsOrder.add(rolePermission);
|
||||
}
|
||||
return projRoleService.updateProjectRolePermission(projectId, projectRole, rolePermissionsOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,12 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -31,6 +37,8 @@ import org.apache.cloudstack.context.CallContext;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@APICommand(name = "addAccountToProject", description = "Adds account to a project", responseObject = SuccessResponse.class, since = "3.0.0",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
@ -56,6 +64,14 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd {
|
||||
@Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, description = "email to which invitation to the project is going to be sent")
|
||||
private String email;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = CommandType.UUID, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the project role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectRoleId;
|
||||
|
||||
@Parameter(name = ApiConstants.ROLE_TYPE, type = BaseCmd.CommandType.STRING,
|
||||
description = "Project role type to be assigned to the user - Admin/Regular; default: Regular")
|
||||
private String roleType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -72,6 +88,21 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd {
|
||||
return email;
|
||||
}
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public ProjectAccount.Role getRoleType() {
|
||||
if (!Strings.isNullOrEmpty(roleType)) {
|
||||
String role = roleType.substring(0, 1).toUpperCase() + roleType.substring(1).toLowerCase();
|
||||
if (!EnumUtils.isValidEnum(ProjectAccount.Role.class, role)) {
|
||||
throw new InvalidParameterValueException("Only Admin or Regular project role types are valid");
|
||||
}
|
||||
return Enum.valueOf(ProjectAccount.Role.class, role);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
@ -88,7 +119,7 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd {
|
||||
}
|
||||
|
||||
CallContext.current().setEventDetails("Project ID: " + projectId + "; accountName " + accountName);
|
||||
boolean result = _projectService.addAccountToProject(getProjectId(), getAccountName(), getEmail());
|
||||
boolean result = _projectService.addAccountToProject(getProjectId(), getAccountName(), getEmail(), getProjectRoleId(), getRoleType());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
@ -110,6 +141,11 @@ public class AddAccountToProjectCmd extends BaseAsyncCmd {
|
||||
return _projectService.getProjectOwner(getProjectId()).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_PROJECT_ACCOUNT_ADD;
|
||||
|
||||
@ -0,0 +1,150 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@APICommand(name = AddUserToProjectCmd.APINAME, description = "Adds user to a project", responseObject = SuccessResponse.class, since = "4.14",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User})
|
||||
public class AddUserToProjectCmd extends BaseAsyncCmd {
|
||||
public static final String APINAME = "addUserToProject";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID,
|
||||
type = BaseCmd.CommandType.UUID,
|
||||
entityType = ProjectResponse.class,
|
||||
required = true,
|
||||
description = "ID of the project to add the user to")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Name of the user to be added to the project")
|
||||
private String username;
|
||||
|
||||
@Parameter(name = ApiConstants.EMAIL, type = CommandType.STRING, description = "email ID of user to which invitation to the project is going to be sent")
|
||||
private String email;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = BaseCmd.CommandType.UUID, entityType = ProjectRoleResponse.class,
|
||||
description = "ID of the project role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long projectRoleId;
|
||||
|
||||
@Parameter(name = ApiConstants.ROLE_TYPE, type = BaseCmd.CommandType.STRING,
|
||||
description = "Project role type to be assigned to the user - Admin/Regular")
|
||||
private String roleType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getEmail() { return email; }
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public ProjectAccount.Role getRoleType() {
|
||||
if (!Strings.isNullOrEmpty(roleType)) {
|
||||
String role = roleType.substring(0, 1).toUpperCase() + roleType.substring(1).toLowerCase();
|
||||
if (!EnumUtils.isValidEnum(ProjectAccount.Role.class, role)) {
|
||||
throw new InvalidParameterValueException("Only Admin or Regular project role types are valid");
|
||||
}
|
||||
return Enum.valueOf(ProjectAccount.Role.class, role);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_PROJECT_USER_ADD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Adding user "+getUsername()+" to Project "+getProjectId();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
validateInput();
|
||||
boolean result = _projectService.addUserToProject(getProjectId(), getUsername(), getEmail(), getProjectRoleId(), getRoleType());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add account to the project");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void validateInput() {
|
||||
if (email == null && username == null) {
|
||||
throw new InvalidParameterValueException("Must specify atleast username");
|
||||
}
|
||||
if (email != null && username == null) {
|
||||
throw new InvalidParameterValueException("Must specify username for given email ID");
|
||||
}
|
||||
if (getProjectId() < 1L) {
|
||||
throw new InvalidParameterValueException("Invalid Project ID provided");
|
||||
}
|
||||
if (projectRoleId != null && projectRoleId < 1L) {
|
||||
throw new InvalidParameterValueException("Invalid Project role ID provided");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return CallContext.current().getCallingAccountId();
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -97,6 +99,11 @@ public class DeleteAccountFromProjectCmd extends BaseAsyncCmd {
|
||||
return _projectService.getProjectOwner(projectId).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE;
|
||||
|
||||
@ -0,0 +1,118 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.project.DeleteProjectCmd;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.projects.Project;
|
||||
|
||||
@APICommand(name = DeleteUserFromProjectCmd.APINAME, description = "Deletes user from the project", responseObject = SuccessResponse.class, since = "4.15.0",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User})
|
||||
public class DeleteUserFromProjectCmd extends BaseAsyncCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(DeleteProjectCmd.class.getName());
|
||||
public static final String APINAME = "deleteUserFromProject";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Parameter(name = ApiConstants.PROJECT_ID,
|
||||
type = BaseCmd.CommandType.UUID,
|
||||
entityType = ProjectResponse.class,
|
||||
required = true,
|
||||
description = "ID of the project to remove the user from")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_ID, type = BaseCmd.CommandType.UUID, entityType = UserResponse.class,
|
||||
required = true, description = "Id of the user to be removed from the project")
|
||||
private Long userId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_PROJECT_USER_REMOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Removing user " + userId + " from project: " + projectId;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Project project = _projectService.getProject(projectId);
|
||||
if (project == null) {
|
||||
throw new InvalidParameterValueException("Unable to find project by ID " + projectId);
|
||||
}
|
||||
return _projectService.getProjectOwner(projectId).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails("Project ID: " + projectId + "; user ID: " + userId);
|
||||
boolean result = _projectService.deleteUserFromProject(getProjectId(), getUserId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete account from the project");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,8 +16,6 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.account;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
@ -25,6 +23,9 @@ import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectAccountResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectRoleResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@ -45,9 +46,15 @@ public class ListProjectAccountsCmd extends BaseListCmd {
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "list accounts of the project by account name")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_ID, type = CommandType.UUID, entityType = UserResponse.class, description = "list invitation by user ID")
|
||||
private Long userId;
|
||||
|
||||
@Parameter(name = ApiConstants.ROLE, type = CommandType.STRING, description = "list accounts of the project by role")
|
||||
private String role;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ROLE_ID, type = CommandType.UUID, entityType = ProjectRoleResponse.class, description = "list accounts of the project by project role id")
|
||||
private Long projectRoleId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -64,6 +71,12 @@ public class ListProjectAccountsCmd extends BaseListCmd {
|
||||
return role;
|
||||
}
|
||||
|
||||
public Long getUserId() { return userId; }
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -69,6 +71,11 @@ public class ActivateProjectCmd extends BaseAsyncCmd {
|
||||
return _projectService.getProjectOwner(getId()).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(id);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -16,18 +16,19 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
@ -49,9 +50,16 @@ public class CreateProjectCmd extends BaseAsyncCreateCmd {
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account who will be Admin for the project")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_ID, type = CommandType.UUID, entityType = UserResponse.class,
|
||||
description = "user ID of the account to be assigned as owner of the project i.e., Project Admin", since = "4.15.0")
|
||||
private Long userId;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning a project")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "ID of the account owning a project")
|
||||
private Long accountId;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, validations = ApiArgValidator.NotNullOrEmpty, description = "name of the project")
|
||||
private String name;
|
||||
|
||||
@ -73,16 +81,24 @@ public class CreateProjectCmd extends BaseAsyncCreateCmd {
|
||||
public Long getDomainId() {
|
||||
if (domainId != null) {
|
||||
return domainId;
|
||||
} else {
|
||||
return CallContext.current().getCallingAccount().getDomainId();
|
||||
}
|
||||
|
||||
return CallContext.current().getCallingAccount().getDomainId();
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public String getDisplayText() {
|
||||
return displayText;
|
||||
}
|
||||
@ -96,10 +112,13 @@ public class CreateProjectCmd extends BaseAsyncCreateCmd {
|
||||
public long getEntityOwnerId() {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) {
|
||||
if ((accountName != null && domainId == null)) {
|
||||
throw new InvalidParameterValueException("Account name and domain id must be specified together");
|
||||
}
|
||||
|
||||
if (userId != null && (accountId == null && domainId == null)) {
|
||||
throw new InvalidParameterValueException("Account ID and Domain ID must be specified with userID");
|
||||
}
|
||||
if (accountName != null) {
|
||||
return _accountService.finalizeOwner(caller, accountName, domainId, null).getId();
|
||||
}
|
||||
@ -126,7 +145,7 @@ public class CreateProjectCmd extends BaseAsyncCreateCmd {
|
||||
@Override
|
||||
public void create() throws ResourceAllocationException {
|
||||
CallContext.current().setEventDetails("Project Name: " + getName());
|
||||
Project project = _projectService.createProject(getName(), getDisplayText(), getAccountName(), getDomainId());
|
||||
Project project = _projectService.createProject(getName(), getDisplayText(), getAccountName(), getDomainId(), getUserId(), getAccountId());
|
||||
if (project != null) {
|
||||
this.setEntityId(project.getId());
|
||||
this.setEntityUuid(project.getUuid());
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -96,4 +98,9 @@ public class DeleteProjectCmd extends BaseAsyncCmd {
|
||||
return _projectService.getProjectOwner(id).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -53,6 +54,9 @@ public class ListProjectInvitationsCmd extends BaseListAccountResourcesCmd {
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ProjectInvitationResponse.class, description = "list invitations by id")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_ID, type = CommandType.UUID, entityType = UserResponse.class, description = "list invitation by user ID")
|
||||
private Long userId;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
@ -72,6 +76,10 @@ public class ListProjectInvitationsCmd extends BaseListAccountResourcesCmd {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
|
||||
@ -63,6 +63,9 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd {
|
||||
@Parameter(name = ApiConstants.TAGS, type = CommandType.MAP, description = "List projects by tags (key/value pairs)")
|
||||
private Map tags;
|
||||
|
||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "List projects by username")
|
||||
private String username;
|
||||
|
||||
@Parameter(name = ApiConstants.DETAILS,
|
||||
type = CommandType.LIST,
|
||||
collectionType = CommandType.STRING,
|
||||
@ -89,6 +92,10 @@ public class ListProjectsCmd extends BaseListAccountResourcesCmd {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -98,4 +100,9 @@ public class SuspendProjectCmd extends BaseAsyncCmd {
|
||||
return _projectService.getProjectOwner(id).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -25,12 +25,17 @@ import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@APICommand(name = "updateProject", description = "Updates a project", responseObject = ProjectResponse.class, since = "3.0.0",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
@ -52,6 +57,17 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
|
||||
@Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, description = "display text of the project")
|
||||
private String displayText;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_ID, type = CommandType.UUID, entityType = UserResponse.class, description = "ID of the user to be promoted/demoted")
|
||||
private Long userId;
|
||||
|
||||
@Parameter(name = ApiConstants.ROLE_TYPE, type = CommandType.STRING, description = "Account level role to be assigned to the user/account : Admin/Regular")
|
||||
private String roleType;
|
||||
|
||||
@Parameter(name = ApiConstants.SWAP_OWNER, type = CommandType.BOOLEAN, description = "when true, it swaps ownership with the account/ user provided. " +
|
||||
"Ideally to be used when a single project administrator is present. In case of multiple project admins, swapowner is to be set to false," +
|
||||
"to promote or demote the user/account based on the roleType (Regular or Admin) provided. Defaults to true")
|
||||
private Boolean swapOwner;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -68,11 +84,34 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
|
||||
return displayText;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public ProjectAccount.Role getRoleType(String role) {
|
||||
String type = role.substring(0, 1).toUpperCase() + role.substring(1).toLowerCase();
|
||||
if (!EnumUtils.isValidEnum(ProjectAccount.Role.class, type)) {
|
||||
throw new InvalidParameterValueException("Only Admin or Regular project role types are valid");
|
||||
}
|
||||
return Enum.valueOf(ProjectAccount.Role.class, type);
|
||||
}
|
||||
|
||||
public ProjectAccount.Role getAccountRole() {
|
||||
if (!Strings.isNullOrEmpty(roleType)) {
|
||||
return getRoleType(roleType);
|
||||
}
|
||||
return ProjectAccount.Role.Regular;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
public Boolean isSwapOwner() {
|
||||
return swapOwner != null ? swapOwner : true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Project project = _projectService.getProject(id);
|
||||
@ -84,6 +123,11 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
|
||||
return _projectService.getProjectOwner(id).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEntityOwnerIds() {
|
||||
return _projectService.getProjectOwners(id);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -91,7 +135,17 @@ public class UpdateProjectCmd extends BaseAsyncCmd {
|
||||
@Override
|
||||
public void execute() throws ResourceAllocationException {
|
||||
CallContext.current().setEventDetails("Project id: " + getId());
|
||||
Project project = _projectService.updateProject(getId(), getDisplayText(), getAccountName());
|
||||
if (getAccountName() != null && getUserId() != null) {
|
||||
throw new InvalidParameterValueException("Account name and user ID are mutually exclusive. Provide either account name" +
|
||||
"to update account or user ID to update the user of the project");
|
||||
}
|
||||
|
||||
Project project = null;
|
||||
if (isSwapOwner()) {
|
||||
project = _projectService.updateProject(getId(), getDisplayText(), getAccountName());
|
||||
} else {
|
||||
project = _projectService.updateProject(getId(), getDisplayText(), getAccountName(), getUserId(), getAccountRole());
|
||||
}
|
||||
if (project != null) {
|
||||
ProjectResponse response = _responseGenerator.createProjectResponse(project);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -16,17 +16,18 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.project;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.user.Account;
|
||||
@ -46,6 +47,10 @@ public class UpdateProjectInvitationCmd extends BaseAsyncCmd {
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "account that is joining the project")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.USER_ID, type = BaseCmd.CommandType.UUID, entityType = UserResponse.class,
|
||||
description = "User UUID, required for adding account from external provisioning system")
|
||||
private Long userId;
|
||||
|
||||
@Parameter(name = ApiConstants.TOKEN,
|
||||
type = CommandType.STRING,
|
||||
description = "list invitations for specified account; this parameter has to be specified with domainId")
|
||||
@ -65,6 +70,8 @@ public class UpdateProjectInvitationCmd extends BaseAsyncCmd {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getUserId() { return userId; }
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
@ -93,8 +100,15 @@ public class UpdateProjectInvitationCmd extends BaseAsyncCmd {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
CallContext.current().setEventDetails("Project id: " + projectId + "; accountName " + accountName + "; accept " + getAccept());
|
||||
boolean result = _projectService.updateInvitation(projectId, accountName, token, getAccept());
|
||||
String eventDetails = "Project id: " + projectId + ";";
|
||||
if (accountName != null) {
|
||||
eventDetails += " accountName: " + accountName + ";";
|
||||
} else if (userId != null) {
|
||||
eventDetails += " userId: " + userId + ";";
|
||||
}
|
||||
eventDetails += " accept " + getAccept();
|
||||
CallContext.current().setEventDetails(eventDetails);
|
||||
boolean result = _projectService.updateInvitation(projectId, accountName, userId, token, getAccept());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.acl.Rule;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class BaseRolePermissionResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.RULE)
|
||||
@Param(description = "the api name or wildcard rule")
|
||||
private String rule;
|
||||
|
||||
@SerializedName(ApiConstants.PERMISSION)
|
||||
@Param(description = "the permission type of the api name or wildcard rule, allow/deny")
|
||||
private String rulePermission;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the role permission")
|
||||
private String ruleDescription;
|
||||
|
||||
public String getRule() {
|
||||
return rule;
|
||||
}
|
||||
|
||||
public void setRule(Rule rule) {
|
||||
if (rule != null) {
|
||||
this.rule = rule.getRuleString();
|
||||
}
|
||||
}
|
||||
|
||||
public String getRulePermission() {
|
||||
return rulePermission;
|
||||
}
|
||||
|
||||
public void setRulePermission(Permission rulePermission) {
|
||||
if (rulePermission != null) {
|
||||
this.rulePermission = rulePermission.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.ruleDescription = description;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class BaseRoleResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the role")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the name of the role")
|
||||
private String roleName;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the role")
|
||||
private String roleDescription;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setRoleName(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.roleDescription = description;
|
||||
}
|
||||
}
|
||||
@ -18,14 +18,13 @@ package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = ProjectAccount.class)
|
||||
@SuppressWarnings("unused")
|
||||
@ -46,10 +45,22 @@ public class ProjectAccountResponse extends BaseResponse implements ControlledVi
|
||||
@Param(description = "the name of the account")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.USERNAME)
|
||||
@Param(description = "Name of the user")
|
||||
private String username;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_TYPE)
|
||||
@Param(description = "account type (admin, domain-admin, user)")
|
||||
private Short accountType;
|
||||
|
||||
@SerializedName(ApiConstants.USER_ID)
|
||||
@Param(description = "Id of the user")
|
||||
private String userId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ROLE_ID)
|
||||
@Param(description = "Id of the project role associated with the account/user")
|
||||
private String projectRoleId;
|
||||
|
||||
@SerializedName(ApiConstants.ROLE)
|
||||
@Param(description = "account role in the project (regular,owner)")
|
||||
private String role;
|
||||
@ -99,6 +110,12 @@ public class ProjectAccountResponse extends BaseResponse implements ControlledVi
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) { this.userId = userId; }
|
||||
|
||||
public void setProjectRoleId(String projectRoleId) {
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
public void setUsers(List<UserResponse> users) {
|
||||
this.users = users;
|
||||
}
|
||||
@ -106,4 +123,8 @@ public class ProjectAccountResponse extends BaseResponse implements ControlledVi
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,14 +16,13 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.projects.ProjectInvitation;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = ProjectInvitation.class)
|
||||
@SuppressWarnings("unused")
|
||||
@ -44,6 +43,10 @@ public class ProjectInvitationResponse extends BaseResponse implements Controlle
|
||||
@Param(description = "the domain id the project belongs to")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.USER_ID)
|
||||
@Param(description = "the User ID")
|
||||
private String userId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "the domain name where the project belongs to")
|
||||
private String domainName;
|
||||
@ -89,6 +92,8 @@ public class ProjectInvitationResponse extends BaseResponse implements Controlle
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) { this.userId = userId; }
|
||||
|
||||
public void setInvitationState(String invitationState) {
|
||||
this.invitationState = invitationState;
|
||||
}
|
||||
|
||||
@ -18,8 +18,7 @@ package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
@ -27,6 +26,7 @@ import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = Project.class)
|
||||
public class ProjectResponse extends BaseResponse implements ResourceLimitAndCountResponse {
|
||||
@ -55,6 +55,10 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
||||
@Param(description = "the account name of the project's owner")
|
||||
private String ownerName;
|
||||
|
||||
@SerializedName(ApiConstants.OWNER)
|
||||
@Param(description = "the account name of the project's owners")
|
||||
private List<Map<String, String>> owners;
|
||||
|
||||
@SerializedName("projectaccountname")
|
||||
@Param(description="the project account name of the project")
|
||||
private String projectAccountName;
|
||||
@ -422,4 +426,7 @@ public class ProjectResponse extends BaseResponse implements ResourceLimitAndCou
|
||||
this.secondaryStorageAvailable = secondaryStorageAvailable;
|
||||
}
|
||||
|
||||
public void setOwners(List<Map<String, String>> owners) {
|
||||
this.owners = owners;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = ProjectRolePermission.class)
|
||||
public class ProjectRolePermissionResponse extends BaseRolePermissionResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the project role permission")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ROLE_ID)
|
||||
@Param(description = "the ID of the project role to which the role permission belongs")
|
||||
private String projectRoleId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the ID of the project")
|
||||
private String projectId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ROLE_NAME)
|
||||
@Param(description = "the name of the project role to which the role permission belongs")
|
||||
private String projectRoleName;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
public String getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public String getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public void setProjectRoleId(String projectRoleId) {
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
public String getProjectRoleName() {
|
||||
return projectRoleName;
|
||||
}
|
||||
|
||||
public void setProjectRoleName(String projectRoleName) {
|
||||
this.projectRoleName = projectRoleName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = ProjectRole.class)
|
||||
public class ProjectRoleResponse extends BaseRoleResponse {
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the id of the project")
|
||||
private String projectId;
|
||||
|
||||
public String getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
}
|
||||
@ -17,16 +17,15 @@
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.acl.Rule;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = RolePermission.class)
|
||||
public class RolePermissionResponse extends BaseResponse {
|
||||
public class RolePermissionResponse extends BaseRolePermissionResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the role permission")
|
||||
private String id;
|
||||
@ -39,18 +38,6 @@ public class RolePermissionResponse extends BaseResponse {
|
||||
@Param(description = "the name of the role to which the role permission belongs")
|
||||
private String roleName;
|
||||
|
||||
@SerializedName(ApiConstants.RULE)
|
||||
@Param(description = "the api name or wildcard rule")
|
||||
private String rule;
|
||||
|
||||
@SerializedName(ApiConstants.PERMISSION)
|
||||
@Param(description = "the permission type of the api name or wildcard rule, allow/deny")
|
||||
private String rulePermission;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the role permission")
|
||||
private String ruleDescription;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@ -74,28 +61,4 @@ public class RolePermissionResponse extends BaseResponse {
|
||||
public void setRoleName(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public String getRule() {
|
||||
return rule;
|
||||
}
|
||||
|
||||
public void setRule(Rule rule) {
|
||||
if (rule != null) {
|
||||
this.rule = rule.getRuleString();
|
||||
}
|
||||
}
|
||||
|
||||
public String getRulePermission() {
|
||||
return rulePermission;
|
||||
}
|
||||
|
||||
public void setRulePermission(RolePermission.Permission rulePermission) {
|
||||
if (rulePermission != null) {
|
||||
this.rulePermission = rulePermission.name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.ruleDescription = description;
|
||||
}
|
||||
}
|
||||
@ -17,54 +17,31 @@
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
@EntityReference(value = Role.class)
|
||||
public class RoleResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the role")
|
||||
private String id;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the name of the role")
|
||||
private String roleName;
|
||||
@EntityReference(value = Role.class)
|
||||
public class RoleResponse extends BaseRoleResponse {
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "the type of the role")
|
||||
private String roleType;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the role")
|
||||
private String roleDescription;
|
||||
|
||||
@SerializedName(ApiConstants.IS_DEFAULT)
|
||||
@Param(description = "true if role is default, false otherwise")
|
||||
private Boolean isDefault;
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setRoleName(String roleName) {
|
||||
this.roleName = roleName;
|
||||
}
|
||||
|
||||
public void setRoleType(RoleType roleType) {
|
||||
if (roleType != null) {
|
||||
this.roleType = roleType.name();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.roleDescription = description;
|
||||
}
|
||||
|
||||
public void setIsDefault(Boolean isDefault) {
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
@ -21,13 +21,12 @@ import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.cloud.projects.Project;
|
||||
import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.NDC;
|
||||
|
||||
import org.apache.cloudstack.managed.threadlocal.ManagedThreadLocal;
|
||||
|
||||
import com.cloud.exception.CloudAuthenticationException;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.UuidUtils;
|
||||
@ -61,6 +60,7 @@ public class CallContext {
|
||||
private long userId;
|
||||
private final Map<Object, Object> context = new HashMap<Object, Object>();
|
||||
private Project project;
|
||||
private String apiName;
|
||||
|
||||
static EntityManager s_entityMgr;
|
||||
|
||||
@ -335,6 +335,14 @@ public class CallContext {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public String getApiName() {
|
||||
return apiName;
|
||||
}
|
||||
|
||||
public void setApiName(String apiName) {
|
||||
this.apiName = apiName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to display the event to the end user.
|
||||
* @return true - if the event is to be displayed to the end user, false otherwise.
|
||||
|
||||
@ -102,6 +102,11 @@
|
||||
<artifactId>cloud-plugin-acl-dynamic-role-based</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-acl-project-role-based</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-ca-rootca</artifactId>
|
||||
|
||||
@ -46,6 +46,9 @@ public class ProjectAccountVO implements ProjectAccount, InternalIdentity {
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name="user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "account_role")
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private Role accountRole = Role.Regular;
|
||||
@ -53,17 +56,26 @@ public class ProjectAccountVO implements ProjectAccount, InternalIdentity {
|
||||
@Column(name = "project_account_id")
|
||||
long projectAccountId;
|
||||
|
||||
@Column(name = "project_role_id")
|
||||
private Long projectRoleId;
|
||||
|
||||
@Column(name = GenericDao.CREATED_COLUMN)
|
||||
private Date created;
|
||||
|
||||
protected ProjectAccountVO() {
|
||||
}
|
||||
|
||||
public ProjectAccountVO(Project project, long accountId, Role accountRole) {
|
||||
public ProjectAccountVO(Project project, long accountId, Role accountRole, Long userId, Long projectRoleId) {
|
||||
this.accountId = accountId;
|
||||
this.accountRole = accountRole;
|
||||
if (accountRole != null) {
|
||||
this.accountRole = accountRole;
|
||||
} else {
|
||||
this.accountRole = Role.Regular;
|
||||
}
|
||||
this.projectId = project.getId();
|
||||
this.projectAccountId = project.getProjectAccountId();
|
||||
this.userId = userId;
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,6 +93,13 @@ public class ProjectAccountVO implements ProjectAccount, InternalIdentity {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getUserId() { return userId; }
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Role getAccountRole() {
|
||||
return accountRole;
|
||||
@ -91,6 +110,13 @@ public class ProjectAccountVO implements ProjectAccount, InternalIdentity {
|
||||
return projectAccountId;
|
||||
}
|
||||
|
||||
public void setProjectRoleId(Long projectRoleId) {
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getProjectRoleId() { return projectRoleId; }
|
||||
|
||||
public void setAccountRole(Role accountRole) {
|
||||
this.accountRole = accountRole;
|
||||
}
|
||||
|
||||
@ -47,6 +47,13 @@ public class ProjectInvitationVO implements ProjectInvitation {
|
||||
@Column(name = "domain_id")
|
||||
private Long inDomainId;
|
||||
|
||||
@Column(name = "account_role")
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private ProjectAccount.Role accountRole = ProjectAccount.Role.Regular;
|
||||
|
||||
@Column(name = "project_role_id")
|
||||
private Long projectRoleId;
|
||||
|
||||
@Column(name = "token")
|
||||
private String token;
|
||||
|
||||
@ -63,6 +70,9 @@ public class ProjectInvitationVO implements ProjectInvitation {
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long forUserId;
|
||||
|
||||
protected ProjectInvitationVO() {
|
||||
uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
@ -127,6 +137,24 @@ public class ProjectInvitationVO implements ProjectInvitation {
|
||||
return inDomainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectAccount.Role getAccountRole() {
|
||||
return accountRole;
|
||||
}
|
||||
|
||||
public void setAccountRole(ProjectAccount.Role accountRole) {
|
||||
this.accountRole = accountRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public void setProjectRoleId(Long projectRoleId) {
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
@ -146,6 +174,15 @@ public class ProjectInvitationVO implements ProjectInvitation {
|
||||
return forAccountId == null ? -1 : forAccountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getForUserId() {
|
||||
return forUserId == null ? -1 : forUserId;
|
||||
}
|
||||
|
||||
public void setForUserId(Long forUserId) {
|
||||
this.forUserId = forUserId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEntityType() {
|
||||
return ProjectInvitation.class;
|
||||
|
||||
@ -25,10 +25,16 @@ import com.cloud.utils.db.GenericDao;
|
||||
public interface ProjectAccountDao extends GenericDao<ProjectAccountVO, Long> {
|
||||
ProjectAccountVO getProjectOwner(long projectId);
|
||||
|
||||
List<ProjectAccountVO> getProjectOwners(long projectId);
|
||||
|
||||
List<ProjectAccountVO> listByProjectId(long projectId);
|
||||
|
||||
ProjectAccountVO findByProjectIdAccountId(long projectId, long accountId);
|
||||
|
||||
ProjectAccountVO findByProjectIdUserId(long projectId, long accountId, long userId);
|
||||
|
||||
boolean canUserAccessProjectAccount(long accountId, long userId, long projectAccountId);
|
||||
|
||||
boolean canAccessProjectAccount(long accountId, long projectAccountId);
|
||||
|
||||
boolean canModifyProjectAccount(long accountId, long projectAccountId);
|
||||
@ -40,4 +46,8 @@ public interface ProjectAccountDao extends GenericDao<ProjectAccountVO, Long> {
|
||||
Long countByAccountIdAndRole(long accountId, ProjectAccount.Role role);
|
||||
|
||||
void removeAccountFromProjects(long accountId);
|
||||
|
||||
boolean canUserModifyProject(long projectId, long accountId, long userId);
|
||||
|
||||
List<ProjectAccountVO> listUsersOrAccountsByRole(long id);
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ package com.cloud.projects.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -34,9 +33,11 @@ import com.cloud.utils.db.SearchCriteria.Op;
|
||||
@Component
|
||||
public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long> implements ProjectAccountDao {
|
||||
protected final SearchBuilder<ProjectAccountVO> AllFieldsSearch;
|
||||
protected final SearchBuilder<ProjectAccountVO> ProjectAccountSearch;
|
||||
final GenericSearchBuilder<ProjectAccountVO, Long> AdminSearch;
|
||||
final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountSearch;
|
||||
final GenericSearchBuilder<ProjectAccountVO, Long> ProjectAccountsSearch;
|
||||
final GenericSearchBuilder<ProjectAccountVO, Long> CountByRoleSearch;
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(ProjectAccountDaoImpl.class.getName());
|
||||
|
||||
protected ProjectAccountDaoImpl() {
|
||||
@ -45,18 +46,27 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
||||
AllFieldsSearch.and("projectId", AllFieldsSearch.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("projectAccountId", AllFieldsSearch.entity().getProjectAccountId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("userId", AllFieldsSearch.entity().getUserId(), Op.EQ);
|
||||
AllFieldsSearch.and("projectRoleId", AllFieldsSearch.entity().getProjectRoleId(), Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
ProjectAccountSearch = createSearchBuilder();
|
||||
ProjectAccountSearch.and("projectId", ProjectAccountSearch.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
ProjectAccountSearch.and("userId", ProjectAccountSearch.entity().getUserId(), Op.NULL);
|
||||
ProjectAccountSearch.done();
|
||||
|
||||
|
||||
AdminSearch = createSearchBuilder(Long.class);
|
||||
AdminSearch.selectFields(AdminSearch.entity().getProjectId());
|
||||
AdminSearch.and("role", AdminSearch.entity().getAccountRole(), Op.EQ);
|
||||
AdminSearch.and("accountId", AdminSearch.entity().getAccountId(), Op.EQ);
|
||||
AdminSearch.done();
|
||||
|
||||
ProjectAccountSearch = createSearchBuilder(Long.class);
|
||||
ProjectAccountSearch.selectFields(ProjectAccountSearch.entity().getProjectAccountId());
|
||||
ProjectAccountSearch.and("accountId", ProjectAccountSearch.entity().getAccountId(), Op.EQ);
|
||||
ProjectAccountSearch.done();
|
||||
ProjectAccountsSearch = createSearchBuilder(Long.class);
|
||||
ProjectAccountsSearch.selectFields(ProjectAccountsSearch.entity().getProjectAccountId());
|
||||
ProjectAccountsSearch.and("accountId", ProjectAccountsSearch.entity().getAccountId(), Op.EQ);
|
||||
ProjectAccountsSearch.done();
|
||||
|
||||
CountByRoleSearch = createSearchBuilder(Long.class);
|
||||
CountByRoleSearch.select(null, Func.COUNT, CountByRoleSearch.entity().getId());
|
||||
@ -74,6 +84,14 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
public List<ProjectAccountVO> getProjectOwners(long projectId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("role", ProjectAccount.Role.Admin);
|
||||
sc.setParameters("projectId", projectId);
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectAccountVO> listByProjectId(long projectId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
@ -84,13 +102,36 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
||||
|
||||
@Override
|
||||
public ProjectAccountVO findByProjectIdAccountId(long projectId, long accountId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = ProjectAccountSearch.create();
|
||||
sc.setParameters("projectId", projectId);
|
||||
sc.setParameters("accountId", accountId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectAccountVO findByProjectIdUserId(long projectId, long accountId, long userId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("projectId", projectId);
|
||||
sc.setParameters("userId", userId);
|
||||
sc.setParameters("accountId", accountId);
|
||||
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUserAccessProjectAccount(long accountId, long userId, long projectAccountId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
sc.setParameters("userId", userId);
|
||||
sc.setParameters("projectAccountId", projectAccountId);
|
||||
|
||||
if (findOneBy(sc) != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccessProjectAccount(long accountId, long projectAccountId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
@ -120,7 +161,7 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
||||
|
||||
@Override
|
||||
public List<Long> listPermittedAccountIds(long accountId) {
|
||||
SearchCriteria<Long> sc = ProjectAccountSearch.create();
|
||||
SearchCriteria<Long> sc = ProjectAccountsSearch.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
@ -152,4 +193,23 @@ public class ProjectAccountDaoImpl extends GenericDaoBase<ProjectAccountVO, Long
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUserModifyProject(long projectId, long accountId, long userId) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("role", ProjectAccount.Role.Admin);
|
||||
sc.setParameters("projectId",projectId);
|
||||
sc.setParameters("accountId", accountId);
|
||||
sc.setParameters("userId", userId);
|
||||
if (findOneBy(sc) != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectAccountVO> listUsersOrAccountsByRole(long id) {
|
||||
SearchCriteria<ProjectAccountVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("projectRoleId", id);
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ import com.cloud.utils.db.GenericDao;
|
||||
public interface ProjectInvitationDao extends GenericDao<ProjectInvitationVO, Long> {
|
||||
ProjectInvitationVO findByAccountIdProjectId(long accountId, long projectId, State... inviteState);
|
||||
|
||||
ProjectInvitationVO findByUserIdProjectId(long userId, long accountId, long projectId, State... inviteState);
|
||||
|
||||
List<ProjectInvitationVO> listExpiredInvitations();
|
||||
|
||||
boolean expirePendingInvitations(long timeOut);
|
||||
|
||||
@ -19,7 +19,6 @@ package com.cloud.projects.dao;
|
||||
import java.sql.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -35,11 +34,13 @@ public class ProjectInvitationDaoImpl extends GenericDaoBase<ProjectInvitationVO
|
||||
private static final Logger s_logger = Logger.getLogger(ProjectInvitationDaoImpl.class);
|
||||
protected final SearchBuilder<ProjectInvitationVO> AllFieldsSearch;
|
||||
protected final SearchBuilder<ProjectInvitationVO> InactiveSearch;
|
||||
protected final SearchBuilder<ProjectInvitationVO> ProjectAccountInviteSearch;
|
||||
|
||||
protected ProjectInvitationDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getForAccountId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("projectId", AllFieldsSearch.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("userId", AllFieldsSearch.entity().getForUserId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("created", AllFieldsSearch.entity().getCreated(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("projectAccountId", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
@ -48,6 +49,12 @@ public class ProjectInvitationDaoImpl extends GenericDaoBase<ProjectInvitationVO
|
||||
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
ProjectAccountInviteSearch = createSearchBuilder();
|
||||
ProjectAccountInviteSearch.and("accountId", ProjectAccountInviteSearch.entity().getForAccountId(), SearchCriteria.Op.EQ);
|
||||
ProjectAccountInviteSearch.and("projectId", ProjectAccountInviteSearch.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
ProjectAccountInviteSearch.and("userId", ProjectAccountInviteSearch.entity().getForUserId(), SearchCriteria.Op.NULL);
|
||||
ProjectAccountInviteSearch.done();
|
||||
|
||||
InactiveSearch = createSearchBuilder();
|
||||
InactiveSearch.and("id", InactiveSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
InactiveSearch.and("accountId", InactiveSearch.entity().getForAccountId(), SearchCriteria.Op.EQ);
|
||||
@ -59,7 +66,7 @@ public class ProjectInvitationDaoImpl extends GenericDaoBase<ProjectInvitationVO
|
||||
|
||||
@Override
|
||||
public ProjectInvitationVO findByAccountIdProjectId(long accountId, long projectId, State... inviteState) {
|
||||
SearchCriteria<ProjectInvitationVO> sc = AllFieldsSearch.create();
|
||||
SearchCriteria<ProjectInvitationVO> sc = ProjectAccountInviteSearch.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
sc.setParameters("projectId", projectId);
|
||||
if (inviteState != null && inviteState.length > 0) {
|
||||
@ -69,6 +76,21 @@ public class ProjectInvitationDaoImpl extends GenericDaoBase<ProjectInvitationVO
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectInvitationVO findByUserIdProjectId(long userId, long accountId, long projectId, State... inviteState) {
|
||||
SearchCriteria<ProjectInvitationVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("userId", userId);
|
||||
sc.setParameters("accountId", accountId);
|
||||
if (projectId != -1) {
|
||||
sc.setParameters("projectId", projectId);
|
||||
}
|
||||
if (inviteState != null && inviteState.length > 0) {
|
||||
sc.setParameters("state", (Object[])inviteState);
|
||||
}
|
||||
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectInvitationVO> listExpiredInvitations() {
|
||||
SearchCriteria<ProjectInvitationVO> sc = AllFieldsSearch.create();
|
||||
|
||||
@ -27,6 +27,8 @@ import com.cloud.utils.db.GenericDao;
|
||||
public interface UserDao extends GenericDao<UserVO, Long> {
|
||||
UserVO getUser(String username, String password);
|
||||
|
||||
UserVO getUserByName(String username, Long domainId);
|
||||
|
||||
UserVO getUser(String username);
|
||||
|
||||
UserVO getUser(long userId);
|
||||
|
||||
@ -19,6 +19,8 @@ package com.cloud.user.dao;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.user.UserVO;
|
||||
@ -38,6 +40,9 @@ public class UserDaoImpl extends GenericDaoBase<UserVO, Long> implements UserDao
|
||||
protected SearchBuilder<UserVO> SecretKeySearch;
|
||||
protected SearchBuilder<UserVO> RegistrationTokenSearch;
|
||||
|
||||
@Inject
|
||||
private AccountDao accountDao;
|
||||
|
||||
protected UserDaoImpl() {
|
||||
UsernameSearch = createSearchBuilder();
|
||||
UsernameSearch.and("username", UsernameSearch.entity().getUsername(), SearchCriteria.Op.EQ);
|
||||
@ -77,6 +82,17 @@ public class UserDaoImpl extends GenericDaoBase<UserVO, Long> implements UserDao
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVO getUserByName(String username, Long domainId) {
|
||||
List<UserVO> users = findUsersByName(username);
|
||||
for (UserVO u : users) {
|
||||
if (accountDao.findActiveAccountById(u.getAccountId(), domainId) != null) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserVO> listByAccount(long accountId) {
|
||||
SearchCriteria<UserVO> sc = AccountIdSearch.create();
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "project_role_permissions")
|
||||
public class ProjectRolePermissionVO extends RolePermissionBaseVO implements ProjectRolePermission {
|
||||
|
||||
@Column(name = "project_id")
|
||||
private long projectId;
|
||||
|
||||
@Column(name = "project_role_id")
|
||||
private long projectRoleId;
|
||||
|
||||
@Column(name = "sort_order")
|
||||
private long sortOrder = 0;
|
||||
|
||||
public ProjectRolePermissionVO() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ProjectRolePermissionVO(final long projectId, final long projectRoleId, final String rule, final Permission permission, final String description) {
|
||||
super(rule, permission, description);
|
||||
this.projectId = projectId;
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public void setProjectRoleId(long projectRoleId) {
|
||||
this.projectRoleId = projectRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(long projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public long getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public void setSortOrder(long sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
@Entity
|
||||
@Table(name = "project_role")
|
||||
@SuppressWarnings("unused")
|
||||
public class ProjectRoleVO implements ProjectRole {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
private Date removed;
|
||||
|
||||
public ProjectRoleVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public ProjectRoleVO(final String name, final String description, final Long projectId) {
|
||||
this();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(Long projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
@MappedSuperclass
|
||||
public class RolePermissionBaseVO implements RolePermissionEntity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "rule")
|
||||
private String rule;
|
||||
|
||||
@Column(name = "permission", nullable = false)
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private Permission permission = Permission.DENY;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
public RolePermissionBaseVO() { this.uuid = UUID.randomUUID().toString(); }
|
||||
|
||||
public RolePermissionBaseVO(final String rule, final Permission permission, final String description) {
|
||||
this();
|
||||
this.rule = rule;
|
||||
this.permission = permission;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rule getRule() {
|
||||
return new Rule(rule);
|
||||
}
|
||||
|
||||
public void setRule(String rule) {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
public void setPermission(Permission permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
}
|
||||
@ -19,61 +19,23 @@ package org.apache.cloudstack.acl;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "role_permissions")
|
||||
public class RolePermissionVO implements RolePermission {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid;
|
||||
public class RolePermissionVO extends RolePermissionBaseVO implements RolePermission {
|
||||
|
||||
@Column(name = "role_id")
|
||||
private long roleId;
|
||||
|
||||
@Column(name = "rule")
|
||||
private String rule;
|
||||
|
||||
@Column(name = "permission", nullable = false)
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private Permission permission = RolePermission.Permission.DENY;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "sort_order")
|
||||
private long sortOrder = 0;
|
||||
|
||||
public RolePermissionVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
public RolePermissionVO() { super(); }
|
||||
|
||||
public RolePermissionVO(final long roleId, final String rule, final Permission permission, final String description) {
|
||||
this();
|
||||
public RolePermissionVO(final Long roleId, final String rule, final Permission permission, final String description) {
|
||||
super(rule, permission, description);
|
||||
this.roleId = roleId;
|
||||
this.rule = rule;
|
||||
this.permission = permission;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public long getRoleId() {
|
||||
@ -84,32 +46,6 @@ public class RolePermissionVO implements RolePermission {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rule getRule() {
|
||||
return new Rule(rule);
|
||||
}
|
||||
|
||||
public void setRule(String rule) {
|
||||
this.rule = rule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
public void setPermission(Permission permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public long getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
@ -117,4 +53,5 @@ public class RolePermissionVO implements RolePermission {
|
||||
public void setSortOrder(long sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRoleVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ProjectRoleDao extends GenericDao<ProjectRoleVO, Long> {
|
||||
List<ProjectRoleVO> findByName(String name, Long projectId);
|
||||
List<ProjectRoleVO> findAllRoles(Long projectId);
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRoleVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
public class ProjectRoleDaoImpl extends GenericDaoBase<ProjectRoleVO, Long> implements ProjectRoleDao{
|
||||
private final SearchBuilder<ProjectRoleVO> ProjectRoleSearch;
|
||||
|
||||
public ProjectRoleDaoImpl() {
|
||||
super();
|
||||
|
||||
ProjectRoleSearch = createSearchBuilder();
|
||||
ProjectRoleSearch.and("name", ProjectRoleSearch.entity().getName(), SearchCriteria.Op.LIKE);
|
||||
ProjectRoleSearch.and("project_id", ProjectRoleSearch.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
ProjectRoleSearch.done();
|
||||
|
||||
}
|
||||
@Override
|
||||
public List<ProjectRoleVO> findByName(String name, Long projectId) {
|
||||
SearchCriteria<ProjectRoleVO> sc = ProjectRoleSearch.create();
|
||||
if (!Strings.isNullOrEmpty(name)) {
|
||||
sc.setParameters("name", "%" + name + "%");
|
||||
}
|
||||
if (projectId != null) {
|
||||
sc.setParameters("project_id", projectId);
|
||||
}
|
||||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectRoleVO> findAllRoles(Long projectId) {
|
||||
SearchCriteria<ProjectRoleVO> sc = ProjectRoleSearch.create();
|
||||
if (projectId != null) {
|
||||
sc.setParameters("project_id", projectId);
|
||||
}
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermissionVO;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ProjectRolePermissionsDao extends GenericDao<ProjectRolePermissionVO, Long> {
|
||||
List<ProjectRolePermissionVO> findAllByRoleIdSorted(Long roleId, Long projectId);
|
||||
boolean update(final ProjectRole role, final Long projectId, final List<ProjectRolePermission> newOrder);
|
||||
boolean update(final ProjectRole role, ProjectRolePermission rolePermission, Permission permission);
|
||||
ProjectRolePermissionVO persist(final ProjectRolePermissionVO projectRolePermissionVO);
|
||||
}
|
||||
@ -0,0 +1,147 @@
|
||||
// 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.
|
||||
|
||||
package org.apache.cloudstack.acl.dao;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermissionVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.utils.db.Attribute;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallback;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
public class ProjectRolePermissionsDaoImpl extends GenericDaoBase<ProjectRolePermissionVO, Long> implements ProjectRolePermissionsDao{
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ProjectRolePermissionsDaoImpl.class);
|
||||
private final SearchBuilder<ProjectRolePermissionVO> ProjectRolePermissionsSearch;
|
||||
private Attribute sortOrderAttribute;
|
||||
|
||||
public ProjectRolePermissionsDaoImpl() {
|
||||
super();
|
||||
|
||||
ProjectRolePermissionsSearch = createSearchBuilder();
|
||||
ProjectRolePermissionsSearch.and("uuid", ProjectRolePermissionsSearch.entity().getUuid(), SearchCriteria.Op.EQ);
|
||||
ProjectRolePermissionsSearch.and("projectRoleId", ProjectRolePermissionsSearch.entity().getProjectRoleId(), SearchCriteria.Op.EQ);
|
||||
ProjectRolePermissionsSearch.and("projectId", ProjectRolePermissionsSearch.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
ProjectRolePermissionsSearch.and("sortOrder", ProjectRolePermissionsSearch.entity().getSortOrder(), SearchCriteria.Op.EQ);
|
||||
ProjectRolePermissionsSearch.done();
|
||||
|
||||
sortOrderAttribute = _allAttributes.get("sortOrder");
|
||||
|
||||
assert (sortOrderAttribute != null) : "Couldn't find one of these attributes";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectRolePermissionVO> findAllByRoleIdSorted(Long roleId, Long projectId) {
|
||||
final SearchCriteria<ProjectRolePermissionVO> sc = ProjectRolePermissionsSearch.create();
|
||||
if (roleId != null && roleId > 0L) {
|
||||
sc.setParameters("projectRoleId", roleId);
|
||||
}
|
||||
if (projectId != null && projectId > 0L) {
|
||||
sc.setParameters("projectId", projectId);
|
||||
}
|
||||
final Filter searchBySorted = new Filter(ProjectRolePermissionVO.class, "sortOrder", true, null, null);
|
||||
final List<ProjectRolePermissionVO> projectRolePermissionList = listBy(sc, searchBySorted);
|
||||
if (projectRolePermissionList == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return projectRolePermissionList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(ProjectRole role, Long projectId, List<ProjectRolePermission> newOrder) {
|
||||
if (role == null || newOrder == null || newOrder.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
final String failMsg = "Project role's rule permissions list has changed while you were making updates, aborted re-ordering of rules. Please try again.";
|
||||
final List<ProjectRolePermissionVO> currentOrder = findAllByRoleIdSorted(role.getId(), projectId);
|
||||
if (role.getId() < 1L || newOrder.size() != currentOrder.size()) {
|
||||
throw new CloudRuntimeException(failMsg);
|
||||
}
|
||||
Set<Long> newOrderSet = new HashSet<>();
|
||||
newOrderSet = newOrder.stream().map(perm -> perm.getId()).collect(Collectors.toSet());
|
||||
|
||||
Set<Long> currOrderSet = new HashSet<>();
|
||||
currOrderSet = currentOrder.stream().map(perm -> perm.getId()).collect(Collectors.toSet());
|
||||
|
||||
long sortOrder = 0L;
|
||||
if (!newOrderSet.equals(currOrderSet)) {
|
||||
throw new CloudRuntimeException(failMsg);
|
||||
}
|
||||
for (ProjectRolePermission projectRolePermission : newOrder) {
|
||||
final SearchCriteria<ProjectRolePermissionVO> sc = ProjectRolePermissionsSearch.create();
|
||||
sc.setParameters("uuid", projectRolePermission.getUuid());
|
||||
sc.setParameters("projectRoleId", role.getId());
|
||||
sc.setParameters("projectId", role.getProjectId());
|
||||
sc.setParameters("sortOrder", projectRolePermission.getSortOrder());
|
||||
|
||||
final UpdateBuilder ub = getUpdateBuilder(projectRolePermission);
|
||||
ub.set(projectRolePermission, sortOrderAttribute, sortOrder);
|
||||
final int result = update(ub, sc, null);
|
||||
if (result < 1) {
|
||||
throw new CloudRuntimeException(failMsg);
|
||||
}
|
||||
sortOrder++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(ProjectRole role, ProjectRolePermission rolePermission, Permission permission) {
|
||||
if (role == null || rolePermission == null || permission == null) {
|
||||
return false;
|
||||
}
|
||||
ProjectRolePermissionVO projectRolePermissionVO = findById(rolePermission.getId());
|
||||
if (projectRolePermissionVO == null) {
|
||||
return false;
|
||||
}
|
||||
projectRolePermissionVO.setPermission(permission);
|
||||
return update(rolePermission.getId(), projectRolePermissionVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectRolePermissionVO persist(final ProjectRolePermissionVO item) {
|
||||
item.setSortOrder(0);
|
||||
final List<ProjectRolePermissionVO> permissionsList = findAllByRoleIdSorted(item.getProjectRoleId(), item.getProjectId());
|
||||
if (permissionsList != null && permissionsList.size() > 0) {
|
||||
ProjectRolePermission lastRule = permissionsList.get(permissionsList.size() - 1);
|
||||
item.setSortOrder(lastRule.getSortOrder() + 1);
|
||||
}
|
||||
return super.persist(item);
|
||||
}
|
||||
}
|
||||
@ -17,13 +17,14 @@
|
||||
|
||||
package org.apache.cloudstack.acl.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.acl.RolePermission.Permission;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity;
|
||||
import org.apache.cloudstack.acl.RolePermissionVO;
|
||||
|
||||
import java.util.List;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface RolePermissionsDao extends GenericDao<RolePermissionVO, Long> {
|
||||
/**
|
||||
@ -48,7 +49,7 @@ public interface RolePermissionsDao extends GenericDao<RolePermissionVO, Long> {
|
||||
* @param permission permission
|
||||
* @return true on success, false if not
|
||||
*/
|
||||
boolean update(final Role role, final RolePermission rolePermission, final Permission permission);
|
||||
boolean update(final Role role, final RolePermission rolePermission, final RolePermissionEntity.Permission permission);
|
||||
|
||||
/**
|
||||
* Returns ordered linked-list of role permission for a given role
|
||||
|
||||
@ -17,6 +17,19 @@
|
||||
|
||||
package org.apache.cloudstack.acl.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
import org.apache.cloudstack.acl.RolePermissionVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.db.Attribute;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
@ -27,18 +40,6 @@ import com.cloud.utils.db.TransactionCallback;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RolePermission;
|
||||
import org.apache.cloudstack.acl.RolePermission.Permission;
|
||||
import org.apache.cloudstack.acl.RolePermissionVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public class RolePermissionsDaoImpl extends GenericDaoBase<RolePermissionVO, Long> implements RolePermissionsDao {
|
||||
|
||||
@ -41,6 +41,8 @@
|
||||
<bean id="dedicatedResourceDaoImpl" class="com.cloud.dc.dao.DedicatedResourceDaoImpl" />
|
||||
<bean id="roleDaoImpl" class="org.apache.cloudstack.acl.dao.RoleDaoImpl" />
|
||||
<bean id="rolePermissionsDaoImpl" class="org.apache.cloudstack.acl.dao.RolePermissionsDaoImpl" />
|
||||
<bean id="projectRoleDaoImpl" class="org.apache.cloudstack.acl.dao.ProjectRoleDaoImpl"/>
|
||||
<bean id="projectRolePermissionsDaoImpl" class="org.apache.cloudstack.acl.dao.ProjectRolePermissionsDaoImpl" />
|
||||
<bean id="accountDaoImpl" class="com.cloud.user.dao.AccountDaoImpl" />
|
||||
<bean id="accountDetailsDaoImpl" class="com.cloud.user.AccountDetailsDaoImpl" />
|
||||
<bean id="accountJoinDaoImpl" class="com.cloud.api.query.dao.AccountJoinDaoImpl" />
|
||||
|
||||
@ -19,6 +19,156 @@
|
||||
-- Schema upgrade from 4.14.0.0 to 4.15.0.0
|
||||
--;
|
||||
|
||||
-- Project roles
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`project_role` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(255) UNIQUE,
|
||||
`name` varchar(255) COMMENT 'unique name of the dynamic project role',
|
||||
`removed` datetime COMMENT 'date removed',
|
||||
`description` text COMMENT 'description of the project role',
|
||||
`project_id` bigint(20) unsigned COMMENT 'Id of the project to which the role belongs',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `i_project_role__name` (`name`),
|
||||
UNIQUE KEY (`name`, `project_id`),
|
||||
CONSTRAINT `fk_project_role__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- Project role permissions table
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`project_role_permissions` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`uuid` varchar(255) UNIQUE,
|
||||
`project_id` bigint(20) unsigned NOT NULL COMMENT 'id of the role',
|
||||
`project_role_id` bigint(20) unsigned NOT NULL COMMENT 'id of the role',
|
||||
`rule` varchar(255) NOT NULL COMMENT 'rule for the role, api name or wildcard',
|
||||
`permission` varchar(255) NOT NULL COMMENT 'access authority, allow or deny',
|
||||
`description` text COMMENT 'description of the rule',
|
||||
`sort_order` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT 'permission sort order',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_project_role_permissions__project_role_id` (`project_role_id`),
|
||||
KEY `i_project_role_permissions__sort_order` (`sort_order`),
|
||||
UNIQUE KEY (`project_role_id`, `rule`),
|
||||
CONSTRAINT `fk_project_role_permissions__project_id` FOREIGN KEY(`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_project_role_permissions__project_role_id` FOREIGN KEY (`project_role_id`) REFERENCES `project_role` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- Alter project accounts table to include user_id and project_role_id for role based users in projects
|
||||
ALTER TABLE `cloud`.`project_account`
|
||||
ADD COLUMN `user_id` bigint unsigned COMMENT 'ID of user to be added to the project' AFTER `account_id`,
|
||||
ADD CONSTRAINT `fk_project_account__user_id` FOREIGN KEY `fk_project_account__user_id`(`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE,
|
||||
ADD COLUMN `project_role_id` bigint unsigned COMMENT 'Project role id' AFTER `project_account_id`,
|
||||
ADD CONSTRAINT `fk_project_account__project_role_id` FOREIGN KEY (`project_role_id`) REFERENCES `project_role` (`id`) ON DELETE SET NULL,
|
||||
DROP FOREIGN KEY `fk_project_account__account_id`,
|
||||
DROP INDEX `account_id`;
|
||||
|
||||
ALTER TABLE `cloud`.`project_account`
|
||||
ADD CONSTRAINT `fk_project_account__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE ,
|
||||
ADD CONSTRAINT `uc_project_account__project_id_account_id_user_id` UNIQUE (`project_id`, `account_id`, `user_id`) ;
|
||||
|
||||
-- Alter project invitations table to include user_id for invites sent to specific users of an account
|
||||
ALTER TABLE `cloud`.`project_invitations`
|
||||
ADD COLUMN `user_id` bigint unsigned COMMENT 'ID of user to be added to the project' AFTER `account_id`,
|
||||
ADD COLUMN `account_role` varchar(255) NOT NULL DEFAULT 'Regular' COMMENT 'Account role in the project (Owner or Regular)' AFTER `domain_id`,
|
||||
ADD COLUMN `project_role_id` bigint unsigned COMMENT 'Project role id' AFTER `account_role`,
|
||||
ADD CONSTRAINT `fk_project_invitations__user_id` FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE,
|
||||
ADD CONSTRAINT `fk_project_invitations__project_role_id` FOREIGN KEY (`project_role_id`) REFERENCES `project_role` (`id`) ON DELETE SET NULL,
|
||||
DROP INDEX `project_id`,
|
||||
ADD CONSTRAINT `uc_project_invitations__project_id_account_id_user_id` UNIQUE (`project_id`, `account_id`,`user_id`);
|
||||
|
||||
-- Alter project_invitation_view to incorporate user_id as a field
|
||||
ALTER VIEW `cloud`.`project_invitation_view` AS
|
||||
select
|
||||
project_invitations.id,
|
||||
project_invitations.uuid,
|
||||
project_invitations.email,
|
||||
project_invitations.created,
|
||||
project_invitations.state,
|
||||
project_invitations.project_role_id,
|
||||
projects.id project_id,
|
||||
projects.uuid project_uuid,
|
||||
projects.name project_name,
|
||||
account.id account_id,
|
||||
account.uuid account_uuid,
|
||||
account.account_name,
|
||||
account.type account_type,
|
||||
user.id user_id,
|
||||
domain.id domain_id,
|
||||
domain.uuid domain_uuid,
|
||||
domain.name domain_name,
|
||||
domain.path domain_path
|
||||
from
|
||||
`cloud`.`project_invitations`
|
||||
left join
|
||||
`cloud`.`account` ON project_invitations.account_id = account.id
|
||||
left join
|
||||
`cloud`.`domain` ON project_invitations.domain_id = domain.id
|
||||
left join
|
||||
`cloud`.`projects` ON projects.id = project_invitations.project_id
|
||||
left join
|
||||
`cloud`.`user` ON project_invitations.user_id = user.id;
|
||||
|
||||
-- Alter project_account_view to incorporate user id
|
||||
ALTER VIEW `cloud`.`project_account_view` AS
|
||||
select
|
||||
project_account.id,
|
||||
account.id account_id,
|
||||
account.uuid account_uuid,
|
||||
account.account_name,
|
||||
account.type account_type,
|
||||
user.id user_id,
|
||||
user.uuid user_uuid,
|
||||
user.username user_name,
|
||||
project_account.account_role,
|
||||
project_role.id project_role_id,
|
||||
project_role.uuid project_role_uuid,
|
||||
projects.id project_id,
|
||||
projects.uuid project_uuid,
|
||||
projects.name project_name,
|
||||
domain.id domain_id,
|
||||
domain.uuid domain_uuid,
|
||||
domain.name domain_name,
|
||||
domain.path domain_path
|
||||
from
|
||||
`cloud`.`project_account`
|
||||
inner join
|
||||
`cloud`.`account` ON project_account.account_id = account.id
|
||||
inner join
|
||||
`cloud`.`domain` ON account.domain_id = domain.id
|
||||
inner join
|
||||
`cloud`.`projects` ON projects.id = project_account.project_id
|
||||
left join
|
||||
`cloud`.`project_role` ON project_account.project_role_id = project_role.id
|
||||
left join
|
||||
`cloud`.`user` ON (project_account.user_id = user.id);
|
||||
|
||||
ALTER VIEW `cloud`.`project_view` AS
|
||||
select
|
||||
projects.id,
|
||||
projects.uuid,
|
||||
projects.name,
|
||||
projects.display_text,
|
||||
projects.state,
|
||||
projects.removed,
|
||||
projects.created,
|
||||
projects.project_account_id,
|
||||
account.account_name owner,
|
||||
pacct.account_id,
|
||||
pacct.user_id,
|
||||
domain.id domain_id,
|
||||
domain.uuid domain_uuid,
|
||||
domain.name domain_name,
|
||||
domain.path domain_path
|
||||
from
|
||||
`cloud`.`projects`
|
||||
inner join
|
||||
`cloud`.`domain` ON projects.domain_id = domain.id
|
||||
inner join
|
||||
`cloud`.`project_account` ON projects.id = project_account.project_id
|
||||
and project_account.account_role = 'Admin'
|
||||
inner join
|
||||
`cloud`.`account` ON account.id = project_account.account_id
|
||||
left join
|
||||
`cloud`.`project_account` pacct ON projects.id = pacct.project_id;
|
||||
|
||||
-- Fix Debian 10 32-bit hypervisor mappings on VMware, debian10-32bit OS ID in guest_os table is 292, not 282
|
||||
UPDATE `cloud`.`guest_os_hypervisor` SET guest_os_id=292 WHERE guest_os_id=282 AND hypervisor_type="VMware" AND guest_os_name="debian10Guest";
|
||||
-- Fix CentOS 32-bit mapping for VMware 5.5 which does not have a centos6Guest but only centosGuest and centos64Guest
|
||||
|
||||
@ -905,7 +905,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
|
||||
try {
|
||||
JmxUtil.registerMBean("ClusterManager", "Node " + mshost.getId(), new ClusterManagerMBeanImpl(this, mshost));
|
||||
} catch (final Exception e) {
|
||||
s_logger.warn("Unable to regiester cluster node into JMX monitoring due to exception " + ExceptionUtil.toString(e));
|
||||
s_logger.warn("Unable to register cluster node into JMX monitoring due to exception " + ExceptionUtil.toString(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -985,7 +985,7 @@ public class ClusterManagerImpl extends ManagerBase implements ClusterManager, C
|
||||
|
||||
_mshostPeerDao.clearPeerInfo(_mshostId);
|
||||
|
||||
// use seperate thread for heartbeat updates
|
||||
// use separate thread for heartbeat updates
|
||||
_heartbeatScheduler.scheduleAtFixedRate(getHeartbeatTask(), HeartbeatInterval.value(), HeartbeatInterval.value(), TimeUnit.MILLISECONDS);
|
||||
_notificationExecutor.submit(getNotificationTask());
|
||||
|
||||
|
||||
@ -25,10 +25,12 @@ import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.exception.UnavailableCommandException;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.UnavailableCommandException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
@ -44,7 +46,9 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
||||
private RoleService roleService;
|
||||
|
||||
private List<PluggableService> services;
|
||||
private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<>();
|
||||
private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<RoleType, Set<String>>();
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DynamicRoleBasedAPIAccessChecker.class.getName());
|
||||
|
||||
protected DynamicRoleBasedAPIAccessChecker() {
|
||||
super();
|
||||
@ -84,7 +88,7 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
||||
// Check against current list of permissions
|
||||
for (final RolePermission permission : roleService.findAllPermissionsBy(accountRole.getId())) {
|
||||
if (permission.getRule().matches(commandName)) {
|
||||
if (RolePermission.Permission.ALLOW.equals(permission.getPermission())) {
|
||||
if (Permission.ALLOW.equals(permission.getPermission())) {
|
||||
return true;
|
||||
} else {
|
||||
denyApiAccess(commandName);
|
||||
|
||||
@ -16,13 +16,9 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
import junit.framework.TestCase;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -30,8 +26,16 @@ import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DynamicRoleBasedAPIAccessCheckerTest extends TestCase {
|
||||
@ -117,7 +121,7 @@ public class DynamicRoleBasedAPIAccessCheckerTest extends TestCase {
|
||||
@Test
|
||||
public void testValidAllowRolePermissionApiCheckAccess() {
|
||||
final String allowedApiName = "someAllowedApi";
|
||||
final RolePermission permission = new RolePermissionVO(1L, allowedApiName, RolePermission.Permission.ALLOW, null);
|
||||
final RolePermission permission = new RolePermissionVO(1L, allowedApiName, Permission.ALLOW, null);
|
||||
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
|
||||
assertTrue(apiAccessChecker.checkAccess(getTestUser(), allowedApiName));
|
||||
}
|
||||
@ -125,7 +129,7 @@ public class DynamicRoleBasedAPIAccessCheckerTest extends TestCase {
|
||||
@Test
|
||||
public void testValidAllowRolePermissionWildcardCheckAccess() {
|
||||
final String allowedApiName = "someAllowedApi";
|
||||
final RolePermission permission = new RolePermissionVO(1L, "some*", RolePermission.Permission.ALLOW, null);
|
||||
final RolePermission permission = new RolePermissionVO(1L, "some*", Permission.ALLOW, null);
|
||||
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
|
||||
assertTrue(apiAccessChecker.checkAccess(getTestUser(), allowedApiName));
|
||||
}
|
||||
@ -133,7 +137,7 @@ public class DynamicRoleBasedAPIAccessCheckerTest extends TestCase {
|
||||
@Test
|
||||
public void testValidDenyRolePermissionApiCheckAccess() {
|
||||
final String denyApiName = "someDeniedApi";
|
||||
final RolePermission permission = new RolePermissionVO(1L, denyApiName, RolePermission.Permission.DENY, null);
|
||||
final RolePermission permission = new RolePermissionVO(1L, denyApiName, Permission.DENY, null);
|
||||
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
|
||||
try {
|
||||
apiAccessChecker.checkAccess(getTestUser(), denyApiName);
|
||||
@ -145,7 +149,7 @@ public class DynamicRoleBasedAPIAccessCheckerTest extends TestCase {
|
||||
@Test
|
||||
public void testValidDenyRolePermissionWildcardCheckAccess() {
|
||||
final String denyApiName = "someDenyApi";
|
||||
final RolePermission permission = new RolePermissionVO(1L, "*Deny*", RolePermission.Permission.DENY, null);
|
||||
final RolePermission permission = new RolePermissionVO(1L, "*Deny*", Permission.DENY, null);
|
||||
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
|
||||
try {
|
||||
apiAccessChecker.checkAccess(getTestUser(), denyApiName);
|
||||
|
||||
30
plugins/acl/project-role-based/pom.xml
Normal file
30
plugins/acl/project-role-based/pom.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-plugin-acl-project-role-based</artifactId>
|
||||
<name>Apache CloudStack Plugin - ACL Project Role Based</name>
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<version>4.15.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
</project>
|
||||
@ -0,0 +1,148 @@
|
||||
// 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.
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
|
||||
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.UnavailableCommandException;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
|
||||
public class ProjectRoleBasedApiAccessChecker extends AdapterBase implements APIAclChecker {
|
||||
|
||||
@Inject
|
||||
ProjectAccountDao projectAccountDao;
|
||||
@Inject
|
||||
ProjectRoleService projectRoleService;
|
||||
@Inject
|
||||
RoleService roleService;
|
||||
@Inject
|
||||
AccountService accountService;
|
||||
|
||||
private List<PluggableService> services;
|
||||
private static final Logger LOGGER = Logger.getLogger(ProjectRoleBasedApiAccessChecker.class.getName());
|
||||
protected ProjectRoleBasedApiAccessChecker() {
|
||||
super();
|
||||
}
|
||||
|
||||
private void denyApiAccess(final String commandName) throws PermissionDeniedException {
|
||||
throw new PermissionDeniedException("The API " + commandName + " is blacklisted for the user's/account's project role.");
|
||||
}
|
||||
|
||||
|
||||
public boolean isDisabled() {
|
||||
return !roleService.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkAccess(User user, String apiCommandName) throws PermissionDeniedException {
|
||||
if (isDisabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Account userAccount = accountService.getAccount(user.getAccountId());
|
||||
Project project = CallContext.current().getProject();
|
||||
if (project == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (accountService.isRootAdmin(userAccount.getId()) || accountService.isDomainAdmin(userAccount.getAccountId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ProjectAccount projectUser = projectAccountDao.findByProjectIdUserId(project.getId(), userAccount.getAccountId(), user.getId());
|
||||
if (projectUser != null) {
|
||||
if (projectUser.getAccountRole() == ProjectAccount.Role.Admin) {
|
||||
return true;
|
||||
} else {
|
||||
return isPermitted(project, projectUser, apiCommandName);
|
||||
}
|
||||
}
|
||||
|
||||
ProjectAccount projectAccount = projectAccountDao.findByProjectIdAccountId(project.getId(), userAccount.getAccountId());
|
||||
if (projectAccount != null) {
|
||||
if (projectAccount.getAccountRole() == ProjectAccount.Role.Admin) {
|
||||
return true;
|
||||
} else {
|
||||
return isPermitted(project, projectAccount, apiCommandName);
|
||||
}
|
||||
}
|
||||
// Default deny all
|
||||
if ("updateProjectInvitation".equals(apiCommandName)) {
|
||||
return true;
|
||||
}
|
||||
throw new UnavailableCommandException("The API " + apiCommandName + " does not exist or is not available for this account/user in project "+project.getUuid());
|
||||
}
|
||||
|
||||
private boolean isPermitted(Project project, ProjectAccount projectUser, String apiCommandName) {
|
||||
ProjectRole projectRole = null;
|
||||
if(projectUser.getProjectRoleId() != null) {
|
||||
projectRole = projectRoleService.findProjectRole(projectUser.getProjectRoleId(), project.getId());
|
||||
}
|
||||
|
||||
if (projectRole == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (ProjectRolePermission permission : projectRoleService.findAllProjectRolePermissions(project.getId(), projectRole.getId())) {
|
||||
if (permission.getRule().matches(apiCommandName)) {
|
||||
if (Permission.ALLOW.equals(permission.getPermission())) {
|
||||
return true;
|
||||
} else {
|
||||
denyApiAccess(apiCommandName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return super.start();
|
||||
}
|
||||
|
||||
public List<PluggableService> getServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setServices(List<PluggableService> services) {
|
||||
this.services = services;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
# 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.
|
||||
name=acl-project-role-based
|
||||
parent=api
|
||||
@ -0,0 +1,33 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd"
|
||||
>
|
||||
|
||||
<bean id="ProjectRoleBasedAPIAccessChecker" class="org.apache.cloudstack.acl.ProjectRoleBasedApiAccessChecker" >
|
||||
<property name="services" value="#{apiCommandsRegistry.registered}" />
|
||||
</bean>
|
||||
</beans>
|
||||
@ -16,13 +16,16 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.discovery;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.ReflectUtil;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.ComponentLifecycleBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.APIChecker;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
@ -39,14 +42,13 @@ import org.apache.log4j.Logger;
|
||||
import org.reflections.ReflectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.ReflectUtil;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.ComponentLifecycleBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@Component
|
||||
public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements ApiDiscoveryService {
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<version>4.15.0.0-SNAPSHOT</version>
|
||||
<version>4.15.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
|
||||
@ -32,20 +32,20 @@
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>${cs.jaxb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>${cs.jaxb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>${cs.jaxb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>${cs.jaxb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>${cs.jaxb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>${cs.jaxb.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
<!-- keep in alphabetic order -->
|
||||
<module>acl/dynamic-role-based</module>
|
||||
<module>acl/static-role-based</module>
|
||||
<module>acl/project-role-based</module>
|
||||
|
||||
<module>affinity-group-processors/explicit-dedication</module>
|
||||
<module>affinity-group-processors/host-affinity</module>
|
||||
|
||||
@ -23,15 +23,18 @@ import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
@ -75,12 +78,22 @@ public class AffinityGroupAccessChecker extends DomainChecker {
|
||||
//acl_type account
|
||||
if (caller.getId() != group.getAccountId()) {
|
||||
//check if the group belongs to a project
|
||||
User user = CallContext.current().getCallingUser();
|
||||
ProjectVO project = _projectDao.findByProjectAccountId(group.getAccountId());
|
||||
ProjectAccount userProjectAccount = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
|
||||
if (project != null) {
|
||||
if (AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canModifyProjectAccount(caller.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
} else if (!AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canAccessProjectAccount(caller.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
if (userProjectAccount != null) {
|
||||
if (AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canUserModifyProject(project.getId(), user.getAccountId(), user.getId())) {
|
||||
return true;
|
||||
} else if (!AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canModifyProjectAccount(caller.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
} else if (!AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canAccessProjectAccount(caller.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
|
||||
|
||||
@ -21,9 +21,15 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.ProjectRolePermission;
|
||||
import org.apache.cloudstack.acl.ProjectRoleService;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
@ -32,6 +38,7 @@ import com.cloud.dc.dao.DedicatedResourceDao;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.UnavailableCommandException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.vpc.VpcOffering;
|
||||
@ -40,8 +47,11 @@ import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
import com.cloud.storage.LaunchPermissionVO;
|
||||
import com.cloud.storage.dao.LaunchPermissionDao;
|
||||
@ -64,7 +74,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
@Inject
|
||||
ProjectManager _projectMgr;
|
||||
@Inject
|
||||
ProjectAccountDao _projecAccountDao;
|
||||
ProjectAccountDao _projectAccountDao;
|
||||
@Inject
|
||||
NetworkModel _networkMgr;
|
||||
@Inject
|
||||
@ -79,7 +89,14 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
NetworkOfferingDetailsDao networkOfferingDetailsDao;
|
||||
@Inject
|
||||
VpcOfferingDetailsDao vpcOfferingDetailsDao;
|
||||
@Inject
|
||||
private ProjectRoleService projectRoleService;
|
||||
@Inject
|
||||
private ProjectDao projectDao;
|
||||
@Inject
|
||||
private AccountService accountService;
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(DomainChecker.class.getName());
|
||||
protected DomainChecker() {
|
||||
super();
|
||||
}
|
||||
@ -107,6 +124,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
if (user.getRemoved() != null) {
|
||||
throw new PermissionDeniedException(user + " is no longer active.");
|
||||
}
|
||||
|
||||
Account account = _accountDao.findById(user.getAccountId());
|
||||
return checkAccess(account, domain);
|
||||
}
|
||||
@ -115,7 +133,6 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType)
|
||||
throws PermissionDeniedException {
|
||||
if (entity instanceof VirtualMachineTemplate) {
|
||||
|
||||
VirtualMachineTemplate template = (VirtualMachineTemplate)entity;
|
||||
Account owner = _accountDao.findById(template.getAccountId());
|
||||
// validate that the template is usable by the account
|
||||
@ -154,7 +171,6 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
} else {
|
||||
if (_accountService.isNormalUser(caller.getId())) {
|
||||
Account account = _accountDao.findById(entity.getAccountId());
|
||||
|
||||
if (account != null && account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
//only project owner can delete/modify the project
|
||||
if (accessType != null && accessType == AccessType.ModifyProject) {
|
||||
@ -164,6 +180,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
} else if (!_projectMgr.canAccessProjectAccount(caller, account.getId())) {
|
||||
throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
|
||||
}
|
||||
checkOperationPermitted(caller, entity);
|
||||
} else {
|
||||
if (caller.getId() != entity.getAccountId()) {
|
||||
throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
|
||||
@ -171,10 +188,59 @@ public class DomainChecker extends AdapterBase implements SecurityChecker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkOperationPermitted(Account caller, ControlledEntity entity) {
|
||||
User user = CallContext.current().getCallingUser();
|
||||
Project project = projectDao.findByProjectAccountId(entity.getAccountId());
|
||||
ProjectAccount projectUser = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
|
||||
String apiCommandName = CallContext.current().getApiName();
|
||||
|
||||
if (accountService.isRootAdmin(caller.getId()) || accountService.isDomainAdmin(caller.getAccountId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (projectUser != null) {
|
||||
if (projectUser.getAccountRole() == ProjectAccount.Role.Admin) {
|
||||
return true;
|
||||
} else {
|
||||
return isPermitted(project, projectUser, apiCommandName);
|
||||
}
|
||||
}
|
||||
|
||||
ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(project.getId(), caller.getAccountId());
|
||||
if (projectAccount != null) {
|
||||
if (projectAccount.getAccountRole() == ProjectAccount.Role.Admin) {
|
||||
return true;
|
||||
} else {
|
||||
return isPermitted(project, projectAccount, apiCommandName);
|
||||
}
|
||||
}
|
||||
throw new UnavailableCommandException("The given command '" + apiCommandName + "' either does not exist or is not available for the user");
|
||||
}
|
||||
|
||||
private boolean isPermitted(Project project, ProjectAccount projectUser, String apiCommandName) {
|
||||
ProjectRole projectRole = null;
|
||||
if(projectUser.getProjectRoleId() != null) {
|
||||
projectRole = projectRoleService.findProjectRole(projectUser.getProjectRoleId(), project.getId());
|
||||
}
|
||||
|
||||
if (projectRole == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (ProjectRolePermission permission : projectRoleService.findAllProjectRolePermissions(project.getId(), projectRole.getId())) {
|
||||
if (permission.getRule().matches(apiCommandName)) {
|
||||
if (RolePermissionEntity.Permission.ALLOW.equals(permission.getPermission())) {
|
||||
return true;
|
||||
} else {
|
||||
throw new PermissionDeniedException("The given command '" + apiCommandName + "' either does not exist or is not available for the user");
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean checkAccess(User user, ControlledEntity entity) throws PermissionDeniedException {
|
||||
Account account = _accountDao.findById(user.getAccountId());
|
||||
|
||||
@ -1142,6 +1142,10 @@ public class ApiDBUtils {
|
||||
return s_userDao.findById(userId);
|
||||
}
|
||||
|
||||
public static UserAccountJoinVO findUserAccountById(Long id) {
|
||||
return s_userAccountJoinDao.findById(id);
|
||||
}
|
||||
|
||||
public static UserVm findUserVmById(Long vmId) {
|
||||
return s_userVmDao.findById(vmId);
|
||||
}
|
||||
@ -1833,6 +1837,7 @@ public class ApiDBUtils {
|
||||
}
|
||||
|
||||
public static List<ProjectJoinVO> newProjectView(Project proj) {
|
||||
|
||||
return s_projectJoinDao.newProjectView(proj);
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.resource.RollingMaintenanceManager;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
@ -45,9 +44,6 @@ import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.ApplicationLoadBalancerInstanceResponse;
|
||||
import org.apache.cloudstack.api.response.ApplicationLoadBalancerResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceHostSkippedResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceHostUpdatedResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
|
||||
import org.apache.cloudstack.api.response.ApplicationLoadBalancerRuleResponse;
|
||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
|
||||
@ -68,7 +64,6 @@ import org.apache.cloudstack.api.response.CreateCmdResponse;
|
||||
import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import org.apache.cloudstack.api.response.DomainRouterResponse;
|
||||
import org.apache.cloudstack.api.response.EventResponse;
|
||||
import org.apache.cloudstack.api.response.ExtractResponse;
|
||||
@ -116,6 +111,10 @@ import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceCountResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceHostSkippedResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceHostUpdatedResponse;
|
||||
import org.apache.cloudstack.api.response.RollingMaintenanceResponse;
|
||||
import org.apache.cloudstack.api.response.RouterHealthCheckResultResponse;
|
||||
import org.apache.cloudstack.api.response.SSHKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
|
||||
@ -296,6 +295,7 @@ import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.projects.ProjectInvitation;
|
||||
import com.cloud.region.ha.GlobalLoadBalancerRule;
|
||||
import com.cloud.resource.RollingMaintenanceManager;
|
||||
import com.cloud.server.ResourceTag;
|
||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
|
||||
@ -16,49 +16,45 @@
|
||||
// under the License.
|
||||
package com.cloud.api;
|
||||
|
||||
import com.cloud.api.dispatch.DispatchChainFactory;
|
||||
import com.cloud.api.dispatch.DispatchTask;
|
||||
import com.cloud.api.response.ApiResponseSerializer;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.ActionEventUtils;
|
||||
import com.cloud.event.EventCategory;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.AccountLimitException;
|
||||
import com.cloud.exception.CloudAuthenticationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OriginDeniedException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.RequestLimitException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.UnavailableCommandException;
|
||||
import com.cloud.storage.VolumeApiService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.utils.ConstantTimeComparator;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.HttpUtils;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.ReflectUtil;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.db.UUIDManager;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.exception.ExceptionProxyObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.cloudstack.acl.APIChecker;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
@ -141,43 +137,50 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import com.cloud.api.dispatch.DispatchChainFactory;
|
||||
import com.cloud.api.dispatch.DispatchTask;
|
||||
import com.cloud.api.response.ApiResponseSerializer;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.ActionEventUtils;
|
||||
import com.cloud.event.EventCategory;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.AccountLimitException;
|
||||
import com.cloud.exception.CloudAuthenticationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OriginDeniedException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.RequestLimitException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.UnavailableCommandException;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.storage.VolumeApiService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.utils.ConstantTimeComparator;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.HttpUtils;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.ReflectUtil;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.db.UUIDManager;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.exception.ExceptionProxyObject;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
@Component
|
||||
public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService, Configurable {
|
||||
@ -209,6 +212,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
||||
private EntityManager entityMgr;
|
||||
@Inject
|
||||
private APIAuthenticationManager authManager;
|
||||
@Inject
|
||||
private ProjectDao projectDao;
|
||||
|
||||
private List<PluggableService> pluggableServices;
|
||||
|
||||
@ -843,7 +848,6 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
||||
// if userId not null, that mean that user is logged in
|
||||
if (userId != null) {
|
||||
final User user = ApiDBUtils.findUserById(userId);
|
||||
|
||||
return commandAvailable(remoteAddress, commandName, user);
|
||||
} else {
|
||||
// check against every available command to see if the command exists or not
|
||||
|
||||
@ -47,6 +47,8 @@ import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
|
||||
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
@ -75,6 +77,8 @@ public class ApiServlet extends HttpServlet {
|
||||
ManagedContext managedContext;
|
||||
@Inject
|
||||
APIAuthenticationManager authManager;
|
||||
@Inject
|
||||
private ProjectDao projectDao;
|
||||
|
||||
public ApiServlet() {
|
||||
}
|
||||
@ -202,6 +206,7 @@ public class ApiServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
session = req.getSession(true);
|
||||
|
||||
if (ApiServer.EnableSecureSessionCookie.value()) {
|
||||
resp.setHeader("SET-COOKIE", String.format("JSESSIONID=%s;Secure;HttpOnly;Path=/client", session.getId()));
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
@ -305,13 +310,14 @@ public class ApiServlet extends HttpServlet {
|
||||
} else {
|
||||
CallContext.register(accountMgr.getSystemUser(), accountMgr.getSystemAccount());
|
||||
}
|
||||
|
||||
setProjectContext(params);
|
||||
if (apiServer.verifyRequest(params, userId, remoteAddress)) {
|
||||
auditTrailSb.insert(0, "(userId=" + CallContext.current().getCallingUserId() + " accountId=" + CallContext.current().getCallingAccount().getId() +
|
||||
" sessionId=" + (session != null ? session.getId() : null) + ")");
|
||||
|
||||
// Add the HTTP method (GET/POST/PUT/DELETE) as well into the params map.
|
||||
params.put("httpmethod", new String[]{req.getMethod()});
|
||||
setProjectContext(params);
|
||||
final String response = apiServer.handleRequest(params, responseType, auditTrailSb);
|
||||
HttpUtils.writeHttpResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType, ApiServer.JSONcontentType.value());
|
||||
} else {
|
||||
@ -347,6 +353,41 @@ public class ApiServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
private void setProjectContext(Map<String, Object[]> requestParameters) {
|
||||
final String[] command = (String[])requestParameters.get(ApiConstants.COMMAND);
|
||||
if (command == null) {
|
||||
s_logger.info("missing command, ignoring request...");
|
||||
return;
|
||||
}
|
||||
|
||||
final String commandName = command[0];
|
||||
CallContext.current().setApiName(commandName);
|
||||
for (Map.Entry<String, Object[]> entry: requestParameters.entrySet()) {
|
||||
if (entry.getKey().equals(ApiConstants.PROJECT_ID) || isSpecificAPI(commandName)) {
|
||||
String projectId = null;
|
||||
if (isSpecificAPI(commandName)) {
|
||||
projectId = String.valueOf(requestParameters.entrySet().stream()
|
||||
.filter(e -> e.getKey().equals(ApiConstants.ID))
|
||||
.map(Map.Entry::getValue).findFirst().get()[0]);
|
||||
} else {
|
||||
projectId = String.valueOf(entry.getValue()[0]);
|
||||
}
|
||||
Project project = projectDao.findByUuid(projectId);
|
||||
if (project != null) {
|
||||
CallContext.current().setProject(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSpecificAPI(String commandName) {
|
||||
List<String> commands = Arrays.asList("suspendProject", "updateProject", "activateProject", "deleteProject");
|
||||
if (commands.contains(commandName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//This method will try to get login IP of user even if servlet is behind reverseProxy or loadBalancer
|
||||
static InetAddress getClientAddress(final HttpServletRequest request) throws UnknownHostException {
|
||||
for(final String header : s_clientAddressHeaders) {
|
||||
|
||||
@ -269,20 +269,24 @@ public class ParamProcessWorker implements DispatchWorker {
|
||||
doAccessChecks(cmd, entitiesToAccess);
|
||||
}
|
||||
|
||||
|
||||
private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
// due to deleteAccount design flaw CLOUDSTACK-6588, we should still include those removed account as well to clean up leftover resources from that account
|
||||
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
|
||||
List<Long> entityOwners = cmd.getEntityOwnerIds();
|
||||
Account[] owners = null;
|
||||
if (entityOwners != null) {
|
||||
owners = entityOwners.stream().map(id -> _accountMgr.getAccount(id)).toArray(Account[]::new);
|
||||
} else {
|
||||
owners = new Account[]{_accountMgr.getAccount(cmd.getEntityOwnerId())};
|
||||
}
|
||||
|
||||
if (cmd instanceof BaseAsyncCreateCmd) {
|
||||
// check that caller can access the owner account.
|
||||
_accountMgr.checkAccess(caller, null, false, owner);
|
||||
_accountMgr.checkAccess(caller, null, false, owners);
|
||||
}
|
||||
|
||||
if (!entitiesToAccess.isEmpty()) {
|
||||
// check that caller can access the owner account.
|
||||
_accountMgr.checkAccess(caller, null, false, owner);
|
||||
_accountMgr.checkAccess(caller, null, false, owners);
|
||||
for (Map.Entry<Object,AccessType>entry : entitiesToAccess.entrySet()) {
|
||||
Object entity = entry.getKey();
|
||||
if (entity instanceof ControlledEntity) {
|
||||
|
||||
@ -196,6 +196,7 @@ import com.cloud.projects.ProjectManager;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.projects.dao.ProjectInvitationDao;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.server.ResourceMetaDataService;
|
||||
import com.cloud.server.ResourceTag;
|
||||
@ -223,7 +224,9 @@ import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
@ -410,6 +413,11 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
@Inject
|
||||
private RouterHealthCheckResultDao routerHealthCheckResultDao;
|
||||
|
||||
@Inject
|
||||
private ProjectInvitationDao projectInvitationDao;
|
||||
|
||||
@Inject
|
||||
private UserDao userDao;
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@ -1386,6 +1394,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
String displayText = cmd.getDisplayText();
|
||||
String state = cmd.getState();
|
||||
String accountName = cmd.getAccountName();
|
||||
String username = cmd.getUsername();
|
||||
Long domainId = cmd.getDomainId();
|
||||
String keyword = cmd.getKeyword();
|
||||
Long startIndex = cmd.getStartIndex();
|
||||
@ -1394,8 +1403,11 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
boolean isRecursive = cmd.isRecursive();
|
||||
cmd.getTags();
|
||||
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
User user = CallContext.current().getCallingUser();
|
||||
Long accountId = null;
|
||||
Long userId = null;
|
||||
String path = null;
|
||||
|
||||
Filter searchFilter = new Filter(ProjectJoinVO.class, "id", false, startIndex, pageSize);
|
||||
@ -1419,11 +1431,23 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
}
|
||||
accountId = owner.getId();
|
||||
}
|
||||
if (!Strings.isNullOrEmpty(username)) {
|
||||
User owner = userDao.getUserByName(username, domainId);
|
||||
if (owner == null) {
|
||||
throw new InvalidParameterValueException("Unable to find user " + username + " in domain " + domainId);
|
||||
}
|
||||
userId = owner.getId();
|
||||
if (accountName == null) {
|
||||
accountId = owner.getAccountId();
|
||||
}
|
||||
}
|
||||
} else { // domainId == null
|
||||
if (accountName != null) {
|
||||
throw new InvalidParameterValueException("could not find account " + accountName + " because domain is not specified");
|
||||
}
|
||||
|
||||
if (!Strings.isNullOrEmpty(username)) {
|
||||
throw new InvalidParameterValueException("could not find user " + username + " because domain is not specified");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (accountName != null && !accountName.equals(caller.getAccountName())) {
|
||||
@ -1434,11 +1458,17 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
throw new PermissionDeniedException("Can't list domain id= " + domainId + " projects; unauthorized");
|
||||
}
|
||||
|
||||
if (!Strings.isNullOrEmpty(username) && !username.equals(user.getUsername())) {
|
||||
throw new PermissionDeniedException("Can't list user " + username + " projects; unauthorized");
|
||||
}
|
||||
|
||||
accountId = caller.getId();
|
||||
userId = user.getId();
|
||||
}
|
||||
|
||||
if (domainId == null && accountId == null && (_accountMgr.isNormalUser(caller.getId()) || !listAll)) {
|
||||
accountId = caller.getId();
|
||||
userId = user.getId();
|
||||
} else if (_accountMgr.isDomainAdmin(caller.getId()) || (isRecursive && !listAll)) {
|
||||
DomainVO domain = _domainDao.findById(caller.getDomainId());
|
||||
path = domain.getPath();
|
||||
@ -1452,6 +1482,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
|
||||
if (userId != null) {
|
||||
sb.and().op("userId", sb.entity().getUserId(), Op.EQ);
|
||||
sb.or("userIdNull", sb.entity().getUserId(), Op.NULL);
|
||||
sb.cp();
|
||||
} else {
|
||||
sb.and("userIdNull", sb.entity().getUserId(), Op.NULL);
|
||||
}
|
||||
|
||||
SearchCriteria<ProjectJoinVO> sc = sb.create();
|
||||
|
||||
if (id != null) {
|
||||
@ -1474,6 +1512,10 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sc.setParameters("accountId", accountId);
|
||||
}
|
||||
|
||||
if (userId != null) {
|
||||
sc.setParameters("userId", userId);
|
||||
}
|
||||
|
||||
if (state != null) {
|
||||
sc.addAnd("state", Op.EQ, state);
|
||||
}
|
||||
@ -1525,10 +1567,12 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
boolean activeOnly = cmd.isActiveOnly();
|
||||
Long startIndex = cmd.getStartIndex();
|
||||
Long pageSizeVal = cmd.getPageSizeVal();
|
||||
Long userId = cmd.getUserId();
|
||||
boolean isRecursive = cmd.isRecursive();
|
||||
boolean listAll = cmd.listAll();
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
User callingUser = CallContext.current().getCallingUser();
|
||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
|
||||
@ -1540,7 +1584,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
Filter searchFilter = new Filter(ProjectInvitationJoinVO.class, "id", true, startIndex, pageSizeVal);
|
||||
SearchBuilder<ProjectInvitationJoinVO> sb = _projectInvitationJoinDao.createSearchBuilder();
|
||||
_accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
|
||||
ProjectInvitation invitation = projectInvitationDao.findByUserIdProjectId(callingUser.getId(), callingUser.getAccountId(), projectId == null ? -1 : projectId);
|
||||
sb.and("projectId", sb.entity().getProjectId(), SearchCriteria.Op.EQ);
|
||||
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
|
||||
sb.and("created", sb.entity().getCreated(), SearchCriteria.Op.GT);
|
||||
@ -1553,6 +1597,12 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sc.setParameters("projectId", projectId);
|
||||
}
|
||||
|
||||
if (invitation != null) {
|
||||
sc.setParameters("userId", invitation.getForUserId());
|
||||
} else if (userId != null) {
|
||||
sc.setParameters("userId", userId);
|
||||
}
|
||||
|
||||
if (state != null) {
|
||||
sc.setParameters("state", state);
|
||||
}
|
||||
@ -1566,7 +1616,11 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sc.setParameters("created", new Date((DateUtil.currentGMTTime().getTime()) - _projectMgr.getInvitationTimeout()));
|
||||
}
|
||||
|
||||
return _projectInvitationJoinDao.searchAndCount(sc, searchFilter);
|
||||
Pair<List<ProjectInvitationJoinVO>, Integer> projectInvitations = _projectInvitationJoinDao.searchAndCount(sc, searchFilter);
|
||||
List<ProjectInvitationJoinVO> invitations = projectInvitations.first();
|
||||
invitations = invitations.stream().filter(invite -> invite.getUserId() == null || Long.parseLong(invite.getUserId()) == callingUser.getId()).collect(Collectors.toList());
|
||||
return new Pair<>(invitations, invitations.size());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1582,14 +1636,15 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
public Pair<List<ProjectAccountJoinVO>, Integer> listProjectAccountsInternal(ListProjectAccountsCmd cmd) {
|
||||
long projectId = cmd.getProjectId();
|
||||
String accountName = cmd.getAccountName();
|
||||
Long userId = cmd.getUserId();
|
||||
String role = cmd.getRole();
|
||||
Long startIndex = cmd.getStartIndex();
|
||||
Long pageSizeVal = cmd.getPageSizeVal();
|
||||
|
||||
Long projectRoleId = cmd.getProjectRoleId();
|
||||
// long projectId, String accountName, String role, Long startIndex,
|
||||
// Long pageSizeVal) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
User callingUser = CallContext.current().getCallingUser();
|
||||
// check that the project exists
|
||||
Project project = _projectDao.findById(projectId);
|
||||
|
||||
@ -1599,7 +1654,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
|
||||
// verify permissions - only accounts belonging to the project can list
|
||||
// project's account
|
||||
if (!_accountMgr.isAdmin(caller.getId()) && _projectAccountDao.findByProjectIdAccountId(projectId, caller.getAccountId()) == null) {
|
||||
if (!_accountMgr.isAdmin(caller.getId()) && _projectAccountDao.findByProjectIdUserId(projectId, callingUser.getAccountId(), callingUser.getId()) == null &&
|
||||
_projectAccountDao.findByProjectIdAccountId(projectId, caller.getAccountId()) == null) {
|
||||
throw new PermissionDeniedException("Account " + caller + " is not authorized to list users of the project id=" + projectId);
|
||||
}
|
||||
|
||||
@ -1612,6 +1668,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sb.and("accountName", sb.entity().getAccountName(), Op.EQ);
|
||||
}
|
||||
|
||||
if (userId != null) {
|
||||
sb.and("userId", sb.entity().getUserId(), Op.EQ);
|
||||
}
|
||||
SearchCriteria<ProjectAccountJoinVO> sc = sb.create();
|
||||
|
||||
sc.setParameters("projectId", projectId);
|
||||
@ -1624,6 +1683,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
||||
sc.setParameters("accountName", accountName);
|
||||
}
|
||||
|
||||
if (projectRoleId != null) {
|
||||
sc.setParameters("projectRoleId", projectRoleId);
|
||||
}
|
||||
|
||||
if (userId != null) {
|
||||
sc.setParameters("userId", userId);
|
||||
}
|
||||
|
||||
return _projectAccountJoinDao.searchAndCount(sc, searchFilter);
|
||||
}
|
||||
|
||||
|
||||
@ -26,9 +26,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.domain.Domain;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
import org.apache.cloudstack.api.ApiConstants.DomainDetails;
|
||||
import org.apache.cloudstack.api.ApiConstants.HostDetails;
|
||||
@ -59,6 +56,7 @@ import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.api.query.vo.AccountJoinVO;
|
||||
@ -84,8 +82,10 @@ import com.cloud.api.query.vo.TemplateJoinVO;
|
||||
import com.cloud.api.query.vo.UserAccountJoinVO;
|
||||
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||
import com.cloud.api.query.vo.VolumeJoinVO;
|
||||
import com.cloud.storage.StoragePoolTagVO;
|
||||
import com.cloud.configuration.Resource;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.StoragePoolTagVO;
|
||||
import com.cloud.storage.VolumeStats;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@ -216,7 +216,12 @@ public class ViewResponseHelper {
|
||||
// update user list
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
if (ApiDBUtils.isAdmin(caller)) {
|
||||
List<UserAccountJoinVO> users = ApiDBUtils.findUserViewByAccountId(proj.getAccountId());
|
||||
List<UserAccountJoinVO> users = null;
|
||||
if (proj.getUserUuid() != null) {
|
||||
users = Collections.singletonList(ApiDBUtils.findUserAccountById(proj.getUserId()));
|
||||
} else {
|
||||
users = ApiDBUtils.findUserViewByAccountId(proj.getAccountId());
|
||||
}
|
||||
resp.setUsers(ViewResponseHelper.createUserResponse(users.toArray(new UserAccountJoinVO[users.size()])));
|
||||
}
|
||||
responseList.add(resp);
|
||||
|
||||
@ -52,9 +52,11 @@ public class ProjectAccountJoinDaoImpl extends GenericDaoBase<ProjectAccountJoin
|
||||
|
||||
projectAccountResponse.setProjectId(proj.getProjectUuid());
|
||||
projectAccountResponse.setProjectName(proj.getProjectName());
|
||||
|
||||
projectAccountResponse.setProjectRoleId(proj.getProjectRoleUuid());
|
||||
projectAccountResponse.setAccountId(proj.getAccountUuid());
|
||||
projectAccountResponse.setAccountName(proj.getAccountName());
|
||||
projectAccountResponse.setUserId(proj.getUserUuid());
|
||||
projectAccountResponse.setUsername(proj.getUsername());
|
||||
projectAccountResponse.setAccountType(proj.getAccountType());
|
||||
projectAccountResponse.setRole(proj.getAccountRole().toString());
|
||||
projectAccountResponse.setDomainId(proj.getDomainUuid());
|
||||
|
||||
@ -57,7 +57,11 @@ public class ProjectInvitationJoinDaoImpl extends GenericDaoBase<ProjectInvitati
|
||||
|
||||
if (invite.getAccountName() != null) {
|
||||
response.setAccountName(invite.getAccountName());
|
||||
} else {
|
||||
}
|
||||
if (invite.getUserId() != null) {
|
||||
response.setUserId(invite.getUserId());
|
||||
}
|
||||
if (invite.getEmail() != null) {
|
||||
response.setEmail(invite.getEmail());
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,10 @@ package com.cloud.api.query.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -35,9 +38,14 @@ import com.cloud.api.query.vo.AccountJoinVO;
|
||||
import com.cloud.api.query.vo.ProjectJoinVO;
|
||||
import com.cloud.api.query.vo.ResourceTagJoinVO;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.projects.ProjectAccountVO;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.server.ResourceTag.ResourceObjectType;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
@ -52,6 +60,10 @@ public class ProjectJoinDaoImpl extends GenericDaoBase<ProjectJoinVO, Long> impl
|
||||
private AccountJoinDao _accountJoinDao;
|
||||
@Inject
|
||||
private AccountDao _accountDao;
|
||||
@Inject
|
||||
private ProjectAccountDao projectAccountDao;
|
||||
@Inject
|
||||
private UserDao userDao;
|
||||
|
||||
private final SearchBuilder<ProjectJoinVO> prjSearch;
|
||||
|
||||
@ -82,7 +94,22 @@ public class ProjectJoinDaoImpl extends GenericDaoBase<ProjectJoinVO, Long> impl
|
||||
response.setDomainId(proj.getDomainUuid());
|
||||
response.setDomain(proj.getDomainName());
|
||||
|
||||
response.setOwner(proj.getOwner());
|
||||
List<ProjectAccountVO> projectAccounts = projectAccountDao.listByProjectId(proj.getId());
|
||||
projectAccounts = projectAccounts.stream().filter(projectAccount -> projectAccount.getAccountRole() == ProjectAccount.Role.Admin).collect(Collectors.toList());
|
||||
List<Map<String, String>> ownersList = new ArrayList<>();
|
||||
for (ProjectAccount projectAccount: projectAccounts) {
|
||||
Map<String, String> ownerDetails = new HashMap<>();
|
||||
if (projectAccount.getUserId() != null) {
|
||||
User user = userDao.findById(projectAccount.getUserId());
|
||||
ownerDetails.put("account", _accountDao.findById(projectAccount.getAccountId()).getAccountName());
|
||||
ownerDetails.put("user", user.getUsername());
|
||||
ownerDetails.put("userid", user.getUuid());
|
||||
} else {
|
||||
ownerDetails.put("account", _accountDao.findById(projectAccount.getAccountId()).getAccountName());
|
||||
}
|
||||
ownersList.add(ownerDetails);
|
||||
}
|
||||
response.setOwners(ownersList);
|
||||
|
||||
// update tag information
|
||||
List<ResourceTagJoinVO> tags = ApiDBUtils.listResourceTagViewByResourceUUID(proj.getUuid(), ResourceObjectType.Project);
|
||||
|
||||
@ -72,6 +72,21 @@ public class ProjectAccountJoinVO extends BaseViewVO implements InternalIdentity
|
||||
@Column(name = "project_name")
|
||||
private String projectName;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "user_name")
|
||||
private String username;
|
||||
|
||||
@Column(name = "project_role_id")
|
||||
private Long projectRoleId;
|
||||
|
||||
@Column(name = "project_role_uuid")
|
||||
private String projectRoleUuid;
|
||||
|
||||
@Column(name = "user_uuid")
|
||||
private String userUuid;
|
||||
|
||||
public ProjectAccountJoinVO() {
|
||||
}
|
||||
|
||||
@ -127,4 +142,21 @@ public class ProjectAccountJoinVO extends BaseViewVO implements InternalIdentity
|
||||
public String getProjectName() {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
public Long getUserId() { return userId; }
|
||||
|
||||
public Long getProjectRoleId() {
|
||||
return projectRoleId;
|
||||
}
|
||||
|
||||
public String getProjectRoleUuid() {
|
||||
return projectRoleUuid;
|
||||
}
|
||||
|
||||
public String getUserUuid() { return userUuid; }
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -83,6 +83,9 @@ public class ProjectInvitationJoinVO extends BaseViewVO implements ControlledVie
|
||||
@Column(name = "project_name")
|
||||
private String projectName;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private String userId;
|
||||
|
||||
public ProjectInvitationJoinVO() {
|
||||
}
|
||||
|
||||
@ -162,6 +165,8 @@ public class ProjectInvitationJoinVO extends BaseViewVO implements ControlledVie
|
||||
return domainPath;
|
||||
}
|
||||
|
||||
public String getUserId() { return userId; }
|
||||
|
||||
@Override
|
||||
public Class<?> getEntityType() {
|
||||
return ProjectInvitation.class;
|
||||
|
||||
@ -76,6 +76,9 @@ public class ProjectJoinVO extends BaseViewVO implements InternalIdentity, Ident
|
||||
@Column(name = "domain_path")
|
||||
private String domainPath;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private long userId;
|
||||
|
||||
@Column(name = "project_account_id")
|
||||
private long projectAccountId;
|
||||
|
||||
@ -139,4 +142,8 @@ public class ProjectJoinVO extends BaseViewVO implements InternalIdentity, Ident
|
||||
public long getProjectAccountId() {
|
||||
return projectAccountId;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import java.util.TreeSet;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ -104,11 +105,15 @@ import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
@ -162,6 +167,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
||||
PodVlanMapDao _podVlanMapDao;
|
||||
@Inject
|
||||
VpcGatewayDao _vpcGatewayDao;
|
||||
@Inject
|
||||
ProjectDao projectDao;
|
||||
|
||||
private List<NetworkElement> networkElements;
|
||||
|
||||
@ -1649,9 +1656,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", network does not have an owner");
|
||||
if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT && networkOwner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
User user = CallContext.current().getCallingUser();
|
||||
Project project = projectDao.findByProjectAccountId(network.getAccountId());
|
||||
ProjectAccount projectAccountUser = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
|
||||
if (projectAccountUser != null) {
|
||||
if (!_projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), network.getAccountId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
} else {
|
||||
if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO) network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
|
||||
|
||||
@ -20,6 +20,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
@ -27,6 +28,7 @@ import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.Authenticator;
|
||||
@ -38,7 +40,9 @@ import javax.mail.URLName;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.acl.ProjectRole;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.acl.dao.ProjectRoleDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
@ -74,6 +78,7 @@ import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
@ -122,6 +127,10 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
private ProjectInvitationJoinDao _projectInvitationJoinDao;
|
||||
@Inject
|
||||
protected ResourceTagDao _resourceTagDao;
|
||||
@Inject
|
||||
private ProjectRoleDao projectRoleDao;
|
||||
@Inject
|
||||
private UserDao userDao;
|
||||
|
||||
protected boolean _invitationRequired = false;
|
||||
protected long _invitationTimeOut = 86400000;
|
||||
@ -171,10 +180,38 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
private User validateUser(Long userId, Long accountId, Long domainId) {
|
||||
User user = null;
|
||||
if (userId != null) {
|
||||
user = userDao.findById(userId);
|
||||
if (user == null ) {
|
||||
throw new InvalidParameterValueException("Invalid user ID provided");
|
||||
}
|
||||
if (user.getAccountId() != accountId || _accountDao.findById(user.getAccountId()).getDomainId() != domainId) {
|
||||
throw new InvalidParameterValueException("User doesn't belong to the specified account or domain");
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private User validateUser(Long userId, Long domainId) {
|
||||
User user = null;
|
||||
if (userId != null) {
|
||||
user = userDao.findById(userId);
|
||||
if (user == null) {
|
||||
throw new InvalidParameterValueException("Invalid user ID provided");
|
||||
}
|
||||
if (_accountDao.findById(user.getAccountId()).getDomainId() != domainId) {
|
||||
throw new InvalidParameterValueException("User doesn't belong to the specified account or domain");
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create = true)
|
||||
@DB
|
||||
public Project createProject(final String name, final String displayText, String accountName, final Long domainId) throws ResourceAllocationException {
|
||||
public Project createProject(final String name, final String displayText, String accountName, final Long domainId, final Long userId, final Long accountId) throws ResourceAllocationException {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Account owner = caller;
|
||||
|
||||
@ -188,6 +225,10 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw new InvalidParameterValueException("Account name and domain id must be specified together");
|
||||
}
|
||||
|
||||
if (userId != null && (accountId == null && domainId == null)) {
|
||||
throw new InvalidParameterValueException("Domain ID and account ID must be provided with User ID");
|
||||
}
|
||||
|
||||
if (accountName != null) {
|
||||
owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null);
|
||||
}
|
||||
@ -197,10 +238,13 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw new InvalidParameterValueException("Project with name " + name + " already exists in domain id=" + owner.getDomainId());
|
||||
}
|
||||
|
||||
User user = validateUser(userId, accountId, domainId);
|
||||
|
||||
//do resource limit check
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.project);
|
||||
|
||||
final Account ownerFinal = owner;
|
||||
User finalUser = user;
|
||||
return Transaction.execute(new TransactionCallback<Project>() {
|
||||
@Override
|
||||
public Project doInTransaction(TransactionStatus status) {
|
||||
@ -214,7 +258,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
Project project = _projectDao.persist(new ProjectVO(name, displayText, ownerFinal.getDomainId(), projectAccount.getId()));
|
||||
|
||||
//assign owner to the project
|
||||
assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin);
|
||||
assignAccountToProject(project, ownerFinal.getId(), ProjectAccount.Role.Admin,
|
||||
Optional.ofNullable(finalUser).map(User::getId).orElse(null), null);
|
||||
|
||||
if (project != null) {
|
||||
CallContext.current().setEventDetails("Project id=" + project.getId());
|
||||
@ -241,6 +286,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
//at this point enabling project doesn't require anything, so just update the state
|
||||
@ -261,6 +307,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
_accountMgr.checkAccess(ctx.getCallingAccount(), AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
|
||||
@ -277,11 +324,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
project.setState(State.Disabled);
|
||||
boolean updateResult = _projectDao.update(project.getId(), project);
|
||||
//owner can be already removed at this point, so adding the conditional check
|
||||
Account projectOwner = getProjectOwner(project.getId());
|
||||
if (projectOwner != null) {
|
||||
_resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project);
|
||||
List<Long> projectOwners = getProjectOwners(project.getId());
|
||||
if (projectOwners != null) {
|
||||
for (Long projectOwner : projectOwners)
|
||||
_resourceLimitMgr.decrementResourceCount(projectOwner, ResourceType.project);
|
||||
}
|
||||
|
||||
return updateResult;
|
||||
}
|
||||
});
|
||||
@ -323,7 +370,6 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
|
||||
s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup...");
|
||||
_projectInvitationDao.cleanupInvitations(project.getId());
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
@ -364,8 +410,13 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole) {
|
||||
return _projectAccountDao.persist(new ProjectAccountVO(project, accountId, accountRole));
|
||||
public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole, Long userId, Long projectRoleId) {
|
||||
ProjectAccountVO projectAccountVO = new ProjectAccountVO(project, accountId, accountRole, userId, projectRoleId);
|
||||
return _projectAccountDao.persist(projectAccountVO);
|
||||
}
|
||||
|
||||
public ProjectAccount assignUserToProject(Project project, long userId, long accountId, Role userRole, Long projectRoleId) {
|
||||
return assignAccountToProject(project, accountId, userRole, userId, projectRoleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -404,6 +455,15 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getProjectOwners(long projectId) {
|
||||
List<? extends ProjectAccount> projectAccounts = _projectAccountDao.getProjectOwners(projectId);
|
||||
if (projectAccounts != null || !projectAccounts.isEmpty()) {
|
||||
return projectAccounts.stream().map(acc -> _accountMgr.getAccount(acc.getAccountId()).getId()).collect(Collectors.toList());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectVO findByProjectAccountId(long projectAccountId) {
|
||||
return _projectDao.findByProjectAccountId(projectAccountId);
|
||||
@ -414,6 +474,74 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
return _projectDao.findByProjectAccountIdIncludingRemoved(projectAccountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_USER_ADD, eventDescription = "adding user to project", async = true)
|
||||
public boolean addUserToProject(Long projectId, String username, String email, Long projectRoleId, Role projectRole) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
Project project = getProject(projectId);
|
||||
if (project == null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
|
||||
ex.addProxyObject(String.valueOf(projectId), "projectId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (project.getState() != State.Active) {
|
||||
InvalidParameterValueException ex =
|
||||
new InvalidParameterValueException("Can't add user to the specified project id in state=" + project.getState() + " as it isn't currently active");
|
||||
ex.addProxyObject(project.getUuid(), "projectId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
|
||||
User user = userDao.getUserByName(username, project.getDomainId());
|
||||
if (user == null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Invalid user ID provided");
|
||||
ex.addProxyObject(String.valueOf(username), "userId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
Account userAccount = _accountDao.findById(user.getAccountId());
|
||||
if (_projectAccountDao.findByProjectIdAccountId(projectId, userAccount.getAccountId()) != null) {
|
||||
throw new InvalidParameterValueException("User belongs to account " + userAccount.getAccountId() + " which is already part of the project");
|
||||
}
|
||||
|
||||
ProjectAccount projectAccountUser = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), user.getId());
|
||||
if (projectAccountUser != null) {
|
||||
s_logger.info("User with id: " + user.getId() + " is already added to the project with id: " + projectId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (projectRoleId != null && projectRoleId < 1L) {
|
||||
throw new InvalidParameterValueException("Invalid project role id provided");
|
||||
}
|
||||
|
||||
ProjectRole role = null;
|
||||
if (projectRoleId != null) {
|
||||
role = projectRoleDao.findById(projectRoleId);
|
||||
if (role == null || !role.getProjectId().equals(projectId)) {
|
||||
throw new InvalidParameterValueException("Invalid project role ID for the given project");
|
||||
}
|
||||
}
|
||||
|
||||
if (_invitationRequired) {
|
||||
return inviteUserToProject(project, user, email, projectRole, role);
|
||||
} else {
|
||||
if (username == null) {
|
||||
throw new InvalidParameterValueException("User information (ID) is required to add user to the project");
|
||||
}
|
||||
if (assignUserToProject(project, user.getId(), user.getAccountId(), projectRole,
|
||||
Optional.ofNullable(role).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
return true;
|
||||
}
|
||||
s_logger.warn("Failed to add user to project with id: " + projectId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Project findByNameAndDomainId(String name, long domainId) {
|
||||
return _projectDao.findByNameAndDomain(name, domainId);
|
||||
@ -429,7 +557,12 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
_accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
|
||||
return true;
|
||||
}
|
||||
|
||||
User user = CallContext.current().getCallingUser();
|
||||
ProjectVO project = _projectDao.findByProjectAccountId(accountId);
|
||||
ProjectAccount userProjectAccount = _projectAccountDao.findByProjectIdUserId(project.getId(), user.getAccountId(), user.getId());
|
||||
if (userProjectAccount != null) {
|
||||
return _projectAccountDao.canUserAccessProjectAccount(user.getAccountId(), user.getId(), accountId);
|
||||
}
|
||||
return _projectAccountDao.canAccessProjectAccount(caller.getId(), accountId);
|
||||
}
|
||||
|
||||
@ -443,9 +576,29 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
_accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId()));
|
||||
return true;
|
||||
}
|
||||
|
||||
User user = CallContext.current().getCallingUser();
|
||||
Project project = CallContext.current().getProject();
|
||||
if (project != null) {
|
||||
ProjectAccountVO projectUser = _projectAccountDao.findByProjectIdUserId(project.getId(), caller.getAccountId(), user.getId());
|
||||
if (projectUser != null) {
|
||||
return _projectAccountDao.canUserModifyProject(project.getId(), caller.getAccountId(), user.getId());
|
||||
}
|
||||
}
|
||||
return _projectAccountDao.canModifyProjectAccount(caller.getId(), accountId);
|
||||
}
|
||||
|
||||
private void updateProjectAccount(ProjectAccountVO futureOwner, Role newAccRole, Long accountId) throws ResourceAllocationException {
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), ResourceType.project);
|
||||
futureOwner.setAccountRole(newAccRole);
|
||||
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
||||
if (newAccRole != null && Role.Admin == newAccRole) {
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.project);
|
||||
} else {
|
||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async = true)
|
||||
@ -465,47 +618,47 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
|
||||
if (displayText != null) {
|
||||
project.setDisplayText(displayText);
|
||||
_projectDao.update(projectId, project);
|
||||
}
|
||||
|
||||
if (newOwnerName != null) {
|
||||
//check that the new owner exists
|
||||
Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
|
||||
if (futureOwnerAccount == null) {
|
||||
throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
|
||||
}
|
||||
Account currentOwnerAccount = getProjectOwner(projectId);
|
||||
if (currentOwnerAccount == null) {
|
||||
s_logger.error("Unable to find the current owner for the project id=" + projectId);
|
||||
throw new InvalidParameterValueException("Unable to find the current owner for the project id=" + projectId);
|
||||
}
|
||||
if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
|
||||
ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
|
||||
if (futureOwner == null) {
|
||||
throw new InvalidParameterValueException("Account " + newOwnerName +
|
||||
" doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
||||
if (displayText != null) {
|
||||
project.setDisplayText(displayText);
|
||||
_projectDao.update(projectId, project);
|
||||
}
|
||||
|
||||
//do resource limit check
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
|
||||
if (newOwnerName != null) {
|
||||
//check that the new owner exists
|
||||
Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
|
||||
if (futureOwnerAccount == null) {
|
||||
throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
|
||||
}
|
||||
Account currentOwnerAccount = getProjectOwner(projectId);
|
||||
if (currentOwnerAccount == null) {
|
||||
s_logger.error("Unable to find the current owner for the project id=" + projectId);
|
||||
throw new InvalidParameterValueException("Unable to find the current owner for the project id=" + projectId);
|
||||
}
|
||||
if (currentOwnerAccount.getId() != futureOwnerAccount.getId()) {
|
||||
ProjectAccountVO futureOwner = _projectAccountDao.findByProjectIdAccountId(projectId, futureOwnerAccount.getAccountId());
|
||||
if (futureOwner == null) {
|
||||
throw new InvalidParameterValueException("Account " + newOwnerName +
|
||||
" doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
||||
}
|
||||
|
||||
//unset the role for the old owner
|
||||
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
|
||||
currentOwner.setAccountRole(Role.Regular);
|
||||
_projectAccountDao.update(currentOwner.getId(), currentOwner);
|
||||
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
|
||||
//do resource limit check
|
||||
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project);
|
||||
|
||||
//set new owner
|
||||
futureOwner.setAccountRole(Role.Admin);
|
||||
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
||||
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
|
||||
//unset the role for the old owner
|
||||
ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId());
|
||||
currentOwner.setAccountRole(Role.Regular);
|
||||
_projectAccountDao.update(currentOwner.getId(), currentOwner);
|
||||
_resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project);
|
||||
|
||||
} else {
|
||||
s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
|
||||
}
|
||||
}
|
||||
//set new owner
|
||||
futureOwner.setAccountRole(Role.Admin);
|
||||
_projectAccountDao.update(futureOwner.getId(), futureOwner);
|
||||
_resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project);
|
||||
|
||||
} else {
|
||||
s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -513,9 +666,76 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async = true)
|
||||
public Project updateProject(final long projectId, final String displayText, final String newOwnerName, Long userId,
|
||||
Role newRole) throws ResourceAllocationException {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
//check that the project exists
|
||||
final ProjectVO project = getProject(projectId);
|
||||
|
||||
if (project == null) {
|
||||
throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
//verify permissions
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
List<? extends ProjectAccount> projectOwners = _projectAccountDao.getProjectOwners(projectId);
|
||||
|
||||
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) throws ResourceAllocationException {
|
||||
if (displayText != null) {
|
||||
project.setDisplayText(displayText);
|
||||
_projectDao.update(projectId, project);
|
||||
}
|
||||
if (newOwnerName != null) {
|
||||
//check that the new owner exists
|
||||
Account updatedAcc = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId());
|
||||
if (updatedAcc == null) {
|
||||
throw new InvalidParameterValueException("Unable to find account name=" + newOwnerName + " in domain id=" + project.getDomainId());
|
||||
}
|
||||
ProjectAccountVO newProjectAcc = _projectAccountDao.findByProjectIdAccountId(projectId, updatedAcc.getAccountId());
|
||||
if (newProjectAcc == null) {
|
||||
throw new InvalidParameterValueException("Account " + newOwnerName +
|
||||
" doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
||||
}
|
||||
|
||||
if (isTheOnlyProjectOwner(projectId, newProjectAcc, caller) && newRole != Role.Admin) {
|
||||
throw new InvalidParameterValueException("Cannot demote the only admin of the project");
|
||||
}
|
||||
updateProjectAccount(newProjectAcc, newRole, updatedAcc.getId());
|
||||
} else if (userId != null) {
|
||||
User user = validateUser(userId, project.getDomainId());
|
||||
if (user == null) {
|
||||
throw new InvalidParameterValueException("Unable to find user= " + user.getUsername() + " in domain id = " + project.getDomainId());
|
||||
}
|
||||
ProjectAccountVO newProjectUser = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), userId);
|
||||
if (newProjectUser == null) {
|
||||
throw new InvalidParameterValueException("User " + userId +
|
||||
" doesn't belong to the project. Add it to the project first and then change the project's ownership");
|
||||
}
|
||||
|
||||
if (projectOwners.size() == 1 && newProjectUser.getUserId().equals(projectOwners.get(0).getUserId())
|
||||
&& newRole != Role.Admin ) {
|
||||
throw new InvalidParameterValueException("Cannot demote the only admin of the project");
|
||||
}
|
||||
|
||||
updateProjectAccount(newProjectUser, newRole, user.getAccountId());
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
return _projectDao.findById(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async = true)
|
||||
public boolean addAccountToProject(long projectId, String accountName, String email) {
|
||||
public boolean addAccountToProject(long projectId, String accountName, String email, Long projectRoleId, Role projectRoleType) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
//check that the project exists
|
||||
@ -550,6 +770,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
//verify permissions - only project owner can assign
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
@ -561,13 +782,26 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (projectRoleId != null && projectRoleId < 1L) {
|
||||
throw new InvalidParameterValueException("Invalid project role id provided");
|
||||
}
|
||||
|
||||
ProjectRole projectRole = null;
|
||||
if (projectRoleId != null) {
|
||||
projectRole = projectRoleDao.findById(projectRoleId);
|
||||
if (projectRole == null || projectRole.getProjectId() != projectId) {
|
||||
throw new InvalidParameterValueException("Invalid project role ID for the given project");
|
||||
}
|
||||
}
|
||||
|
||||
if (_invitationRequired) {
|
||||
return inviteAccountToProject(project, account, email);
|
||||
return inviteAccountToProject(project, account, email, projectRoleType, projectRole);
|
||||
} else {
|
||||
if (account == null) {
|
||||
throw new InvalidParameterValueException("Account information is required for assigning account to the project");
|
||||
}
|
||||
if (assignAccountToProject(project, account.getId(), ProjectAccount.Role.Regular) != null) {
|
||||
if (assignAccountToProject(project, account.getId(), projectRoleType, null,
|
||||
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to add account " + accountName + " to project id=" + projectId);
|
||||
@ -576,9 +810,10 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean inviteAccountToProject(Project project, Account account, String email) {
|
||||
private boolean inviteAccountToProject(Project project, Account account, String email, Role role,ProjectRole projectRole) {
|
||||
if (account != null) {
|
||||
if (createAccountInvitation(project, account.getId()) != null) {
|
||||
if (createAccountInvitation(project, account.getId(), null, role,
|
||||
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to generate invitation for account " + account.getAccountName() + " to project id=" + project);
|
||||
@ -589,7 +824,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
if (email != null) {
|
||||
//generate the token
|
||||
String token = generateToken(10);
|
||||
if (generateTokenBasedInvitation(project, email, token) != null) {
|
||||
if (generateTokenBasedInvitation(project, null, email, token, role,
|
||||
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project);
|
||||
@ -600,6 +836,37 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean inviteUserToProject(Project project, User user, String email, Role role, ProjectRole projectRole) {
|
||||
if (email == null) {
|
||||
if (createAccountInvitation(project, user.getAccountId(), user.getId(), role,
|
||||
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to generate invitation for account " + user.getUsername() + " to project id=" + project);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//generate the token
|
||||
String token = generateToken(10);
|
||||
if (generateTokenBasedInvitation(project, user.getId(), email, token, role,
|
||||
Optional.ofNullable(projectRole).map(ProjectRole::getId).orElse(null)) != null) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTheOnlyProjectOwner(Long projectId, ProjectAccount projectAccount, Account caller) {
|
||||
List<? extends ProjectAccount> projectOwners = _projectAccountDao.getProjectOwners(projectId);
|
||||
if ((projectOwners.size() == 1 && projectOwners.get(0).getAccountId() == projectAccount.getAccountId()
|
||||
&& projectAccount.getAccountRole() == Role.Admin )) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE, eventDescription = "removing account from project", async = true)
|
||||
public boolean deleteAccountFromProject(long projectId, String accountName) {
|
||||
@ -628,11 +895,12 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
//verify permissions
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
//Check if the account exists in the project
|
||||
ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
|
||||
ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId());
|
||||
if (projectAccount == null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id");
|
||||
// Use the projectVO object and not the projectAccount object to inject the projectId.
|
||||
@ -641,7 +909,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
}
|
||||
|
||||
//can't remove the owner of the project
|
||||
if (projectAccount.getAccountRole() == Role.Admin) {
|
||||
if (isTheOnlyProjectOwner(projectId, projectAccount, caller)) {
|
||||
InvalidParameterValueException ex =
|
||||
new InvalidParameterValueException("Unable to delete account " + accountName +
|
||||
" from the project with specified id as the account is the owner of the project");
|
||||
@ -652,18 +920,104 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
return deleteAccountFromProject(projectId, account.getId());
|
||||
}
|
||||
|
||||
public ProjectInvitation createAccountInvitation(Project project, Long accountId) {
|
||||
if (activeInviteExists(project, accountId, null)) {
|
||||
throw new InvalidParameterValueException("There is already a pending invitation for account id=" + accountId + " to the project id=" + project);
|
||||
@Override
|
||||
public boolean deleteUserFromProject(long projectId, long userId) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
//check that the project exists
|
||||
Project project = getProject(projectId);
|
||||
|
||||
if (project == null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id");
|
||||
ex.addProxyObject(String.valueOf(projectId), "projectId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
ProjectInvitation invitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), accountId, project.getDomainId(), null, null));
|
||||
User user = userDao.findById(userId);
|
||||
if (user == null) {
|
||||
throw new InvalidParameterValueException("Invalid userId provided");
|
||||
}
|
||||
Account userAcc = _accountDao.findActiveAccountById(user.getAccountId(), project.getDomainId());
|
||||
if (userAcc == null) {
|
||||
InvalidParameterValueException ex =
|
||||
new InvalidParameterValueException("Unable to find user "+ user.getUsername() + " in domain id=" + project.getDomainId());
|
||||
DomainVO domain = ApiDBUtils.findDomainById(project.getDomainId());
|
||||
String domainUuid = String.valueOf(project.getDomainId());
|
||||
if (domain != null) {
|
||||
domainUuid = domain.getUuid();
|
||||
}
|
||||
ex.addProxyObject(domainUuid, "domainId");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return invitation;
|
||||
CallContext.current().setProject(project);
|
||||
//verify permissions
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
//Check if the user exists in the project
|
||||
ProjectAccount projectUser = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), user.getId());
|
||||
if (projectUser == null) {
|
||||
deletePendingInvite(projectId, user);
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException("User " + user.getUsername() + " is not assigned to the project with specified id");
|
||||
// Use the projectVO object and not the projectAccount object to inject the projectId.
|
||||
ex.addProxyObject(project.getUuid(), "projectId");
|
||||
throw ex;
|
||||
}
|
||||
return deleteUserFromProject(projectId, user);
|
||||
}
|
||||
|
||||
private void deletePendingInvite(Long projectId, User user) {
|
||||
ProjectInvitation invite = _projectInvitationDao.findByUserIdProjectId(user.getId(), user.getAccountId(), projectId);
|
||||
if (invite != null) {
|
||||
boolean success = _projectInvitationDao.remove(invite.getId());
|
||||
if (success){
|
||||
s_logger.info("Successfully deleted invite pending for the user : "+user.getUsername());
|
||||
} else {
|
||||
s_logger.info("Failed to delete project invite for user: "+ user.getUsername());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
public boolean activeInviteExists(final Project project, final Long accountId, final String email) {
|
||||
private boolean deleteUserFromProject(Long projectId, User user) {
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
boolean success = true;
|
||||
ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdUserId(projectId, user.getAccountId(), user.getId());
|
||||
success = _projectAccountDao.remove(projectAccount.getId());
|
||||
|
||||
if (success) {
|
||||
s_logger.debug("Removed user " + user.getId() + " from project. Removing any invite sent to the user");
|
||||
ProjectInvitation invite = _projectInvitationDao.findByUserIdProjectId(user.getId(), user.getAccountId(), projectId);
|
||||
if (invite != null) {
|
||||
success = success && _projectInvitationDao.remove(invite.getId());
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ProjectInvitation createAccountInvitation(Project project, Long accountId, Long userId, Role role, Long projectRoleId) {
|
||||
if (activeInviteExists(project, accountId, userId, null)) {
|
||||
throw new InvalidParameterValueException("There is already a pending invitation for account id=" + accountId + " to the project id=" + project);
|
||||
}
|
||||
|
||||
ProjectInvitationVO invitationVO = new ProjectInvitationVO(project.getId(), accountId, project.getDomainId(), null, null);
|
||||
if (userId != null) {
|
||||
invitationVO.setForUserId(userId);
|
||||
}
|
||||
if (role != null) {
|
||||
invitationVO.setAccountRole(role);
|
||||
}
|
||||
if (projectRoleId != null) {
|
||||
invitationVO.setProjectRoleId(projectRoleId);
|
||||
}
|
||||
return _projectInvitationDao.persist(invitationVO);
|
||||
}
|
||||
|
||||
@DB
|
||||
public boolean activeInviteExists(final Project project, final Long accountId, Long userId, final String email) {
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
@ -671,6 +1025,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
ProjectInvitationVO invite = null;
|
||||
if (accountId != null) {
|
||||
invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId());
|
||||
} else if (userId != null) {
|
||||
invite = _projectInvitationDao.findByUserIdProjectId(userId, accountId, project.getId());
|
||||
} else if (email != null) {
|
||||
invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId());
|
||||
}
|
||||
@ -686,6 +1042,8 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
//remove the expired/declined invitation
|
||||
if (accountId != null) {
|
||||
s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project);
|
||||
} else if (userId != null) {
|
||||
s_logger.debug("Removing invitation in state " + invite.getState() + " for user id=" + userId + " to project " + project);
|
||||
} else if (email != null) {
|
||||
s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project);
|
||||
}
|
||||
@ -699,13 +1057,24 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
});
|
||||
}
|
||||
|
||||
public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) {
|
||||
public ProjectInvitation generateTokenBasedInvitation(Project project, Long userId, String email, String token, Role role, Long projectRoleId) {
|
||||
//verify if the invitation was already generated
|
||||
if (activeInviteExists(project, null, email)) {
|
||||
if (activeInviteExists(project, null, null, email)) {
|
||||
throw new InvalidParameterValueException("There is already a pending invitation for email " + email + " to the project id=" + project);
|
||||
}
|
||||
|
||||
ProjectInvitation projectInvitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), null, project.getDomainId(), email, token));
|
||||
ProjectInvitationVO projectInvitationVO = new ProjectInvitationVO(project.getId(), null, project.getDomainId(), email, token);
|
||||
if (userId != null) {
|
||||
projectInvitationVO.setForUserId(userId);
|
||||
}
|
||||
if (role != null) {
|
||||
projectInvitationVO.setAccountRole(role);
|
||||
}
|
||||
if (projectRoleId != null) {
|
||||
projectInvitationVO.setProjectRoleId(projectRoleId);
|
||||
}
|
||||
|
||||
ProjectInvitation projectInvitation = _projectInvitationDao.persist(projectInvitationVO);
|
||||
try {
|
||||
_emailInvite.sendInvite(token, email, project.getId());
|
||||
} catch (Exception ex) {
|
||||
@ -726,23 +1095,19 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
@Override
|
||||
@DB
|
||||
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async = true)
|
||||
public boolean updateInvitation(final long projectId, String accountName, String token, final boolean accept) {
|
||||
public boolean updateInvitation(final long projectId, String accountName, Long userId, String token, final boolean accept) {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Long accountId = null;
|
||||
User user = null;
|
||||
boolean result = true;
|
||||
|
||||
//if accountname and token are null, default accountname to caller's account name
|
||||
if (accountName == null && token == null) {
|
||||
accountName = caller.getAccountName();
|
||||
}
|
||||
|
||||
//check that the project exists
|
||||
final Project project = getProject(projectId);
|
||||
|
||||
if (project == null) {
|
||||
throw new InvalidParameterValueException("Unable to find the project id=" + projectId);
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
if (accountName != null) {
|
||||
//check that account-to-remove exists
|
||||
Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId());
|
||||
@ -752,16 +1117,30 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
|
||||
//verify permissions
|
||||
_accountMgr.checkAccess(caller, null, true, account);
|
||||
|
||||
accountId = account.getId();
|
||||
} else if (userId != null) {
|
||||
user = userDao.findById(userId);
|
||||
if (user == null) {
|
||||
throw new InvalidParameterValueException("Invalid user ID provided. Please provide a valid user ID or " +
|
||||
"account name whose invitation is to be updated");
|
||||
}
|
||||
Account userAccount = _accountDao.findById(user.getAccountId());
|
||||
if (userAccount.getDomainId() != project.getDomainId()) {
|
||||
throw new InvalidParameterValueException("Unable to find user =" + userId + " in domain id=" + project.getDomainId());
|
||||
}
|
||||
} else {
|
||||
accountId = caller.getId();
|
||||
user = CallContext.current().getCallingUser();
|
||||
}
|
||||
|
||||
//check that invitation exists
|
||||
ProjectInvitationVO invite = null;
|
||||
if (token == null) {
|
||||
invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId, ProjectInvitation.State.Pending);
|
||||
if (accountName != null) {
|
||||
invite = _projectInvitationDao.findByAccountIdProjectId(accountId, projectId, ProjectInvitation.State.Pending);
|
||||
} else {
|
||||
invite = _projectInvitationDao.findByUserIdProjectId(user.getId(), user.getAccountId(), projectId, ProjectInvitation.State.Pending);
|
||||
}
|
||||
} else {
|
||||
invite = _projectInvitationDao.findPendingByTokenAndProjectId(token, projectId, ProjectInvitation.State.Pending);
|
||||
}
|
||||
@ -771,10 +1150,11 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
expireInvitation(invite);
|
||||
throw new InvalidParameterValueException("Invitation is expired for account id=" + accountName + " to the project id=" + projectId);
|
||||
} else {
|
||||
|
||||
final ProjectInvitationVO inviteFinal = invite;
|
||||
final Long accountIdFinal = accountId;
|
||||
final String accountNameFinal = accountName;
|
||||
final User finalUser = user;
|
||||
ProjectInvitationVO finalInvite = invite;
|
||||
result = Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
@ -783,25 +1163,32 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined;
|
||||
|
||||
//update invitation
|
||||
s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
|
||||
inviteFinal.setState(newState);
|
||||
result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
|
||||
s_logger.debug("Marking invitation " + inviteFinal + " with state " + newState);
|
||||
inviteFinal.setState(newState);
|
||||
result = _projectInvitationDao.update(inviteFinal.getId(), inviteFinal);
|
||||
|
||||
if (result && accept) {
|
||||
//check if account already exists for the project (was added before invitation got accepted)
|
||||
ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
|
||||
if (projectAccount != null) {
|
||||
s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
|
||||
if (finalInvite.getForUserId() == -1) {
|
||||
ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountIdFinal);
|
||||
if (projectAccount != null) {
|
||||
s_logger.debug("Account " + accountNameFinal + " already added to the project id=" + projectId);
|
||||
} else {
|
||||
assignAccountToProject(project, accountIdFinal, finalInvite.getAccountRole(), null, finalInvite.getProjectRoleId());
|
||||
}
|
||||
} else {
|
||||
assignAccountToProject(project, accountIdFinal, ProjectAccount.Role.Regular);
|
||||
ProjectAccount projectAccount = _projectAccountDao.findByProjectIdUserId(projectId, finalUser.getAccountId(), finalUser.getId());
|
||||
if (projectAccount != null) {
|
||||
s_logger.debug("User " + finalUser.getId() + "has already been added to the project id=" + projectId);
|
||||
} else {
|
||||
assignUserToProject(project, finalInvite.getForUserId(), finalUser.getAccountId(), finalInvite.getAccountRole(), finalInvite.getProjectRoleId());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
|
||||
s_logger.warn("Failed to update project invitation " + inviteFinal + " with state " + newState);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}});
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId);
|
||||
@ -830,6 +1217,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
//verify permissions
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
@ -871,6 +1259,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
if (suspendProject(project)) {
|
||||
@ -911,7 +1300,6 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
class EmailInvite {
|
||||
private Session _smtpSession;
|
||||
private final String _smtpHost;
|
||||
@ -1012,6 +1400,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
|
||||
//check that the project exists
|
||||
Project project = getProject(invitation.getProjectId());
|
||||
|
||||
CallContext.current().setProject(project);
|
||||
//check permissions - only project owner can remove the invitations
|
||||
_accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));
|
||||
|
||||
|
||||
@ -288,7 +288,9 @@ import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.zone.MarkDefaultZoneForAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.AddAccountToProjectCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.AddUserToProjectCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.DeleteAccountFromProjectCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.DeleteUserFromProjectCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
|
||||
@ -696,6 +698,7 @@ import com.cloud.vm.ConsoleProxyVO;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.InstanceGroupVO;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
@ -708,9 +711,8 @@ import com.cloud.vm.dao.ConsoleProxyDao;
|
||||
import com.cloud.vm.dao.InstanceGroupDao;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class ManagementServerImpl extends ManagerBase implements ManagementServer, Configurable {
|
||||
public static final Logger s_logger = Logger.getLogger(ManagementServerImpl.class.getName());
|
||||
@ -2808,7 +2810,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
cmdList.add(MarkDefaultZoneForAccountCmd.class);
|
||||
cmdList.add(UpdateZoneCmd.class);
|
||||
cmdList.add(AddAccountToProjectCmd.class);
|
||||
cmdList.add(AddUserToProjectCmd.class);
|
||||
cmdList.add(DeleteAccountFromProjectCmd.class);
|
||||
cmdList.add(DeleteUserFromProjectCmd.class);
|
||||
cmdList.add(ListAccountsCmd.class);
|
||||
cmdList.add(ListProjectAccountsCmd.class);
|
||||
cmdList.add(AssociateIPAddrCmd.class);
|
||||
|
||||
@ -37,7 +37,6 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.QuerySelector;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
@ -521,6 +520,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("No need to make permission check for System/RootAdmin account, returning true");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2034,7 +2034,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
return caller;
|
||||
}
|
||||
} else {
|
||||
if ((accountName == null && domainId != null) || (accountName != null && domainId == null)) {
|
||||
if (accountName != null && domainId == null) {
|
||||
throw new InvalidParameterValueException("AccountName and domainId must be specified together");
|
||||
}
|
||||
// regular user can't create/list resources for other people
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user