/** * Gets RoleCategory from database using User's Environement * * @param int $roleCategoryId An identifier of the Role Category * @return \Scalr\Model\Entity\RoleCategory Returns RoleCategory entity on success or NULL otherwise * @throws ApiErrorException */ private function getRoleCategory($roleCategoryId) { $criteria = $this->getDefaultCriteria(); $criteria[] = ['id' => $roleCategoryId]; $roleCategory = Entity\RoleCategory::findOne($criteria); if (!$roleCategory) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "The Role Category either does not exist or isn't in scope for the current Environment"); } //To be over-suspicious checking READ access to RoleCategory Entity $this->checkPermissions($roleCategory); return $roleCategory; }
/** * Gets RoleCategory from database using User's Environement * * @param int $roleCategoryId An identifier of the Role Category * @param bool $restrictToCurrentScope optional Whether it should additionally check that role category corresponds to current scope * @return RoleCategory * @throws ApiErrorException */ private function getRoleCategory($roleCategoryId, $restrictToCurrentScope = false) { $criteria = $this->getDefaultCriteria(); $criteria[] = ['id' => $roleCategoryId]; /* @var RoleCategory $roleCategory */ $roleCategory = Entity\RoleCategory::findOne($criteria); if (!$roleCategory) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("The Role Category either does not exist or it is out of %s scope.", ucfirst($this->getScope()))); } //To be over-suspicious checking READ access to RoleCategory Entity $this->checkPermissions($roleCategory); if ($restrictToCurrentScope && $roleCategory->getScope() !== $this->getScope()) { throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf('The Role Category is not either from the %s scope or owned by your %s.', $this->getScope(), $this->getScope())); } return $roleCategory; }
/** * {@inheritdoc} * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity() */ public function validateEntity($entity) { if (!$entity instanceof RoleCategory) { throw new \InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\RoleCategory class")); } if (!preg_match('/^' . RoleCategory::NAME_REGEXP . '$/', $entity->name)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid name of the Role Category. Name should start and end with letter or number and contain only letters, numbers, spaces and dashes.'); } if (strlen($entity->name) > RoleCategory::NAME_LENGTH) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, 'Name should be less than 18 characters'); } if (is_null($entity->id)) { $criteria = $this->controller->getScopeCriteria($entity->getScope()); $criteria[] = ['name' => $entity->name]; if (!empty(RoleCategory::findOne($criteria))) { throw new ApiErrorException(409, ErrorMessage::ERR_UNICITY_VIOLATION, sprintf('Role Category with name %s already exists', $entity->name)); } } else { if (empty(RoleCategory::findPk($entity->id))) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Role Category with id: %d", $entity->id)); } } }
/** * {@inheritdoc} * @see \Scalr\Api\DataType\ApiEntityAdapter::validateEntity() */ public function validateEntity($entity) { if (!$entity instanceof Entity\Role) { throw new \InvalidArgumentException(sprintf("First argument must be instance of Scalr\\Model\\Entity\\Role class")); } if ($entity->id !== null) { if (!is_integer($entity->id)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid value of the identifier"); } //Checks if the role does exist if (!Entity\Role::findPk($entity->id)) { throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, sprintf("Could not find out the Role with ID: %d", $entity->id)); } } //Is this a new Role if (!$entity->id) { $entity->addedByEmail = $this->controller->getUser()->email; $entity->addedByUserId = $this->controller->getUser()->id; } if (!$entity::isValidName($entity->name)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "Invalid name of the Role"); } $entity->description = $entity->description ?: ''; $this->validateString($entity->description, 'Invalid description'); if (!$this->controller->hasPermissions($entity, true)) { //Checks entity level write access permissions throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions"); } //We only allow to either create or modify Environment Scope Roles if ($entity->getScope() !== $this->controller->getScope()) { throw new ApiErrorException(403, ErrorMessage::ERR_SCOPE_VIOLATION, sprintf("Invalid scope")); } //Checks the Role Category if (!empty($entity->catId)) { //Tries to find out the specified Role category $category = Entity\RoleCategory::findPk($entity->catId); if ($category instanceof Entity\RoleCategory) { //Checks if the specified RoleCategory either shared or belongs to User's scope. if ($category->getScope() !== ScopeInterface::SCOPE_SCALR && $category->envId !== $this->controller->getEnvironment()->id) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "The specified category isn't owned by your environment."); } } else { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "The Role category does not exist"); } } else { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Role category should be provided with the request."); } if (empty($entity->osId)) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property 'os.id'"); } //Tries to find out the specified OS if (empty(Entity\Os::findPk($entity->osId))) { throw new ApiErrorException(400, ErrorMessage::ERR_INVALID_VALUE, "OS with id '{$entity->osId}' not found."); } }
/** * @test */ public function testAccountRolesFunctional() { $db = \Scalr::getDb(); $testName = str_replace('-', '', static::getTestName()); $roles = null; $uri = self::getAccountApiUrl('/roles'); do { $query = []; if (isset($roles->pagination->next)) { $parts = parse_url($roles->pagination->next); parse_str($parts['query'], $query); } $describe = $this->request($uri, Request::METHOD_GET, $query); $this->assertDescribeResponseNotEmpty($describe); $this->assertNotEmpty($describe->getBody()); $roles = $describe->getBody(); foreach ($roles->data as $role) { $this->assertRolesObjectNotEmpty($role); if ($role->name == $testName) { $delete = $this->request($uri . '/' . $role->id, Request::METHOD_DELETE); $this->assertEquals(200, $delete->status); } } } while (!empty($roles->pagination->next)); // test create action $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => 'invalid']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid scope'); $create = $this->request($uri, Request::METHOD_POST); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body'); $create = $this->request($uri, Request::METHOD_POST, [], ['invalid' => 'value']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set'); $create = $this->request($uri, Request::METHOD_POST, [], ['id' => 'value']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid name'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => 'invalidName^$&&']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid name of the Role'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'description' => 'invalidDesc<br/>']); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid description'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Role category should be provided'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'category' => ['id' => 'not int']]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid identifier of the category'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'category' => ['id' => -1]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'The Role category does not exist'); $rolesCat = RoleCategory::findOne(); /* @var $rolesCat RoleCategory */ $this->assertNotEmpty($rolesCat); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'category' => ['id' => $rolesCat->id]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_STRUCTURE, "Missed property 'os.id'"); $os = Os::findOne([['status' => Os::STATUS_ACTIVE], ['family' => 'ubuntu'], ['generation' => '12.04']]); /* @var $os Os */ $this->assertNotEmpty($os); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'category' => ['id' => $rolesCat->id], 'os' => ['id' => -1]]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, 'Invalid identifier of the OS'); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'category' => ['id' => $rolesCat->id], 'os' => ['id' => 'invalid']]); $this->assertErrorMessageContains($create, 400, ErrorMessage::ERR_INVALID_VALUE, "OS with id 'invalid' not found."); $create = $this->request($uri, Request::METHOD_POST, [], ['scope' => ScopeInterface::SCOPE_ACCOUNT, 'name' => $testName, 'description' => $testName, 'category' => $rolesCat->id, 'os' => $os->id, 'quickStart' => true, 'deprecated' => true]); $body = $create->getBody(); $this->assertEquals(201, $create->response->getStatus()); $this->assertFetchResponseNotEmpty($create); $this->assertRolesObjectNotEmpty($body->data); $this->assertNotEmpty($body->data->id); $this->assertEquals($testName, $body->data->name); $this->assertEquals($testName, $body->data->description); $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $body->data->scope); $this->assertEquals($rolesCat->id, $body->data->category->id); $this->assertEquals($os->id, $body->data->os->id); $this->assertEquals(true, $body->data->quickStart); $this->assertEquals(true, $body->data->deprecated); // test images actions $roleId = $body->data->id; $imagesUri = $uri . '/' . $roleId . '/images'; $images = null; do { $query = []; if (isset($images->pagination->next)) { $parts = parse_url($images->pagination->next); parse_str($parts['query'], $query); } $describeImages = $this->request($imagesUri, Request::METHOD_GET, $query); $this->assertDescribeResponseNotEmpty($describeImages); $images = $describeImages->getBody(); foreach ($images->data as $imageRole) { $this->assertRoleImageObjectNotEmpty($imageRole); $this->assertEquals($roleId, $imageRole->role->id); $image = Image::findPk($imageRole->image->id); /* @var $image Image */ if ($image->name == $testName) { $delete = $this->request($imagesUri . '/' . $imageRole->image->id, Request::METHOD_DELETE); $this->assertEquals(200, $delete->status); } } } while (!empty($images->pagination->next)); $env = \Scalr_Environment::init()->loadById(static::$testEnvId); $platform = \SERVER_PLATFORMS::EC2; if (!$env->isPlatformEnabled($platform)) { $env->setPlatformConfig([$platform . '.is_enabled' => 1]); } $region = null; $cloudImageId = null; foreach (Aws::getCloudLocations() as $cloudLocation) { $cloudImageId = $this->getNewImageId($env, $cloudLocation); if (!empty($cloudImageId)) { $region = $cloudLocation; break; } } $this->assertNotNull($cloudImageId); $this->assertNotNull($cloudLocation); $image = $this->createEntity(new Image(), ['accountId' => $this->getUser()->accountId, 'name' => $testName, 'osId' => $os->id, 'platform' => $platform, 'cloudLocation' => $region, 'id' => $cloudImageId, 'architecture' => 'x86_64', 'source' => Image::SOURCE_MANUAL, 'status' => Image::STATUS_ACTIVE]); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId + 10], 'image' => ['id' => $image->hash]]); $this->assertErrorMessageStatusEquals(400, $createRoleImage); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_INVALID_VALUE, $createRoleImage); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId]]); $this->assertErrorMessageStatusEquals(400, $createRoleImage); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_INVALID_STRUCTURE, $createRoleImage); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId], 'image' => ['id' => '11111111-1111-1111-1111-111111111111']]); $this->assertErrorMessageStatusEquals(404, $createRoleImage); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_INVALID_VALUE, $createRoleImage); $createRoleImage = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId], 'image' => ['id' => $image->hash]]); $createRoleImageBody = $createRoleImage->getBody(); $this->assertEquals(201, $createRoleImage->response->getStatus()); $this->assertFetchResponseNotEmpty($createRoleImage); $this->assertRoleImageObjectNotEmpty($createRoleImageBody->data); $createRoleImageError = $this->request($imagesUri, Request::METHOD_POST, [], ['role' => ['id' => $roleId], 'image' => ['id' => $image->hash]]); $this->assertErrorMessageStatusEquals(400, $createRoleImageError); $this->assertErrorMessageErrorEquals(ErrorMessage::ERR_BAD_REQUEST, $createRoleImageError); $fetchImage = $this->request($imagesUri . '/' . $createRoleImageBody->data->image->id, Request::METHOD_GET); $fetchImageBody = $fetchImage->getBody(); $this->assertEquals(200, $fetchImage->response->getStatus()); $this->assertFetchResponseNotEmpty($fetchImage); $this->assertImageObjectNotEmpty($fetchImageBody->data); $this->assertEquals($cloudImageId, $fetchImageBody->data->cloudImageId); $this->assertEquals($testName, $fetchImageBody->data->name); // test role images filtering $describeRoleImages = $this->request($imagesUri, Request::METHOD_GET, ['role' => $roleId]); $this->assertDescribeResponseNotEmpty($describeRoleImages); foreach ($describeRoleImages->getBody()->data as $data) { $this->assertRoleImageObjectNotEmpty($data); $this->assertEquals($roleId, $data->role->id); } $describeRoleImages = $this->request($imagesUri, Request::METHOD_GET, ['image' => $image->hash]); $this->assertDescribeResponseNotEmpty($describeRoleImages); foreach ($describeRoleImages->getBody()->data as $data) { $this->assertRoleImageObjectNotEmpty($data); $this->assertEquals($image->hash, $data->image->id); } $describeRoleImages = $this->request($imagesUri, Request::METHOD_GET, ['invalid' => 'value']); $this->assertErrorMessageContains($describeRoleImages, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Unsupported filter'); $currentRole = Role::findPk($roleId); /* @var $currentRole Role */ $this->assertNotEmpty($currentRole); $adminImages = Image::find([['envId' => null], ['status' => Image::STATUS_ACTIVE], ['cloudLocation' => $region]]); $this->assertNotEmpty($adminImages); $adminImage = null; foreach ($adminImages as $aImage) { /* @var $aImage Image */ $imageOs = $aImage->getOs(); if (!empty($imageOs) && $imageOs->generation == $currentRole->getOs()->generation && $imageOs->family == $currentRole->getOs()->family) { $adminImage = $aImage; break; } } /* @var $adminImage Image */ $this->assertNotEmpty($adminImage); $this->assertNotEquals($createRoleImageBody->data->image->id, $adminImage->hash); $replaceImage = $this->request($imagesUri . '/' . $createRoleImageBody->data->image->id . '/actions/replace', Request::METHOD_POST, [], ['role' => $roleId, 'image' => $adminImage->hash]); $replaceImageBody = $replaceImage->getBody(); $this->assertEquals(200, $replaceImage->response->getStatus()); $this->assertFetchResponseNotEmpty($replaceImage); $this->assertRoleImageObjectNotEmpty($replaceImageBody->data); $this->assertEquals($adminImage->hash, $replaceImageBody->data->image->id); $deleteImage = $this->request($imagesUri . '/' . $replaceImageBody->data->image->id, Request::METHOD_DELETE); $this->assertEquals(200, $deleteImage->response->getStatus()); $delete = $this->request(static::getAccountApiUrl("images/{$image->hash}"), Request::METHOD_DELETE); $this->assertEquals(200, $delete->response->getStatus()); // test get action $notFoundRoleId = 10 + $db->GetOne("SELECT MAX(r.id) FROM roles r"); $get = $this->request($uri . '/' . $notFoundRoleId, Request::METHOD_GET); $this->assertErrorMessageContains($get, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "The Role either does not exist or isn't in scope for the current Environment"); $get = $this->request($uri . '/' . $body->data->id, Request::METHOD_GET); $getBody = $get->getBody(); $this->assertEquals(200, $get->response->getStatus()); $this->assertFetchResponseNotEmpty($get); $this->assertRolesObjectNotEmpty($getBody->data); $this->assertEquals($body->data->id, $getBody->data->id); $this->assertEquals($testName, $getBody->data->name); $this->assertEquals($testName, $getBody->data->description); $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $getBody->data->scope); $this->assertEquals($rolesCat->id, $getBody->data->category->id); $this->assertEquals($os->id, $getBody->data->os->id); // test filters $describe = $this->request($uri, Request::METHOD_GET, ['description' => $testName]); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Unsupported filter'); $describe = $this->request($uri, Request::METHOD_GET, ['scope' => 'wrong<br>']); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, 'Unexpected scope value'); $describe = $this->request($uri, Request::METHOD_GET, ['scope' => ScopeInterface::SCOPE_SCALR]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); } $describe = $this->request($uri, Request::METHOD_GET, ['scope' => ScopeInterface::SCOPE_ACCOUNT]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $data->scope); } $describe = $this->request($uri, Request::METHOD_GET, ['name' => $testName]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($testName, $data->name); } $describe = $this->request($uri, Request::METHOD_GET, ['id' => $roleId]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($roleId, $data->id); } $describe = $this->request($uri, Request::METHOD_GET, ['os' => $os->id]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($os->id, $data->os->id); } $describe = $this->request($uri, Request::METHOD_GET, ['os' => 'invalid*&^^%']); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, "Invalid identifier of the OS"); $describe = $this->request($uri, Request::METHOD_GET, ['category' => $rolesCat->id]); $this->assertDescribeResponseNotEmpty($describe); foreach ($describe->getBody()->data as $data) { $this->assertRolesObjectNotEmpty($data); $this->assertEquals($rolesCat->id, $data->category->id); } $describe = $this->request($uri, Request::METHOD_GET, ['category' => '']); $this->assertErrorMessageContains($describe, 400, ErrorMessage::ERR_INVALID_VALUE, "Invalid identifier of the category"); // test modify action $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'Invalid body'); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['id' => 123]); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['invalid' => 'err']); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_STRUCTURE, 'You are trying to set'); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['scope' => 'environment']); $this->assertErrorMessageContains($modify, 400, ErrorMessage::ERR_INVALID_VALUE); $modify = $this->request($uri . '/' . $body->data->id, Request::METHOD_PATCH, [], ['description' => '']); $modifyBody = $modify->getBody(); $this->assertEquals(200, $modify->response->getStatus()); $this->assertFetchResponseNotEmpty($modify); $this->assertRolesObjectNotEmpty($modifyBody->data); $this->assertEquals($body->data->id, $modifyBody->data->id); $this->assertEquals($testName, $modifyBody->data->name); $this->assertEquals('', $modifyBody->data->description); $this->assertEquals(ScopeInterface::SCOPE_ACCOUNT, $modifyBody->data->scope); $this->assertEquals($rolesCat->id, $modifyBody->data->category->id); $this->assertEquals($os->id, $modifyBody->data->os->id); // test delete action $delete = $this->request(static::getAccountApiUrl("/roles/{$notFoundRoleId}"), Request::METHOD_DELETE); $this->assertErrorMessageContains($delete, 404, ErrorMessage::ERR_OBJECT_NOT_FOUND); $delete = $this->request($uri . '/' . $body->data->id, Request::METHOD_DELETE); $this->assertEquals(200, $delete->status); $db->Execute("INSERT INTO roles SET\n name = ?,\n dtadded = NOW(),\n env_id\t = NULL,\n client_id = NULL,\n generation = 2\n ", [$testName]); $insertedId = $db->_insertid(); $db->Execute("INSERT INTO role_images SET\n role_id = ?,\n platform = 'ec2',\n image_id = 'test'\n ", [$insertedId]); $delete = $this->request($uri . '/' . $insertedId, Request::METHOD_DELETE); $db->Execute("DELETE FROM roles WHERE name = ? AND id = ?", [$testName, $insertedId]); $this->assertErrorMessageContains($delete, 403, ErrorMessage::ERR_SCOPE_VIOLATION); }
/** * Returns list Role Categories * @param bool $notEmpty Not empty categories only * @param bool $checkRoleImages Count roles with no images * @return array [id => name] */ public function listRoleCategories($notEmpty = false, $checkRoleImages = false) { $query = "SELECT c.*\n FROM role_categories c "; $where = "WHERE (c.account_id IS NULL AND c.env_id IS NULL) OR (c.account_id = ? AND (c.env_id IS NULL OR c.env_id = ?)) "; $args = [$this->user->getAccountId(), $this->environment->id]; if ($notEmpty) { $query .= "INNER JOIN roles r ON c.id = r.cat_id "; $where .= "AND (r.client_id IS NULL AND r.env_id IS NULL) OR (r.client_id = ? AND (r.env_id IS NULL OR r.env_id = ?)) "; $args[] = $this->user->getAccountId(); $args[] = $this->environment->id; if ($this->request->getScope() == ScopeInterface::SCOPE_ENVIRONMENT && $checkRoleImages) { $query .= "INNER JOIN role_images ri ON ri.role_id = r.id "; $where .= "AND ri.platform IN ('" . implode("','", array_keys(self::loadController('Platforms')->getEnabledPlatforms())) . "') "; } } $query .= $where . "\n GROUP BY c.id\n ORDER BY IF(c.account_id OR c.env_id, 1, 0), IF(c.account_id OR c.env_id, c.name, c.id)\n "; $result = []; foreach ($this->db->GetAll($query, $args) as $c) { $category = new RoleCategory(); $category->load($c); $result[$category->id] = ['id' => $category->id, 'name' => $category->name, 'scope' => $category->getScope()]; } return $result; }
/** * @param JsonData $ids * @throws Exception */ public function xGroupActionHandlerAction(JsonData $ids) { $this->request->restrictAccess('ROLES', 'MANAGE'); $processed = array(); $errors = array(); if (count($ids) == 0) { throw new Exception('Empty id\'s list'); } foreach (RoleCategory::find(['id' => ['$in' => $ids]]) as $category) { /* @var $category RoleCategory */ if ($this->request->hasPermissions($category, true)) { if ($category->getUsed()) { $errors[] = 'Role category is in use and can\'t be removed.'; } else { $processed[] = $category->id; $category->delete(); } } else { $errors[] = 'Insufficient permissions to remove Role Category'; } } $num = count($ids); if (count($processed) == $num) { $this->response->success('Role Categories successfully removed'); } else { array_walk($errors, function (&$item) { $item = '- ' . $item; }); $this->response->warning(sprintf("Successfully removed %d from %d Role Categories. \nFollowing errors occurred:\n%s", count($processed), $num, join($errors, ''))); } $this->response->data(array('processed' => $processed)); }