- Fix tests
- Add new endpoints for retrieving the repo permissions for a robot account - Have the robots list return the number of repositories for which there are permissions - Other UI fixes
This commit is contained in:
parent
bb81c05c03
commit
1f5e6df678
16 changed files with 356 additions and 60 deletions
|
@ -312,9 +312,23 @@ def _list_entity_robots(entity_name):
|
|||
|
||||
def list_entity_robot_tuples(entity_name):
|
||||
return (_list_entity_robots(entity_name)
|
||||
.select(User.username, FederatedLogin.service_ident)
|
||||
.join(RepositoryPermission, JOIN_LEFT_OUTER,
|
||||
on=(RepositoryPermission.user == FederatedLogin.user))
|
||||
.join(Repository, JOIN_LEFT_OUTER)
|
||||
.switch(User)
|
||||
.group_by(User, FederatedLogin)
|
||||
.select(User.username, FederatedLogin.service_ident, fn.Count(Repository.id))
|
||||
.tuples())
|
||||
|
||||
def list_robot_permissions(robot_name):
|
||||
return (RepositoryPermission.select(RepositoryPermission, User, Repository)
|
||||
.join(Repository)
|
||||
.join(Visibility)
|
||||
.switch(RepositoryPermission)
|
||||
.join(Role)
|
||||
.switch(RepositoryPermission)
|
||||
.join(User)
|
||||
.where(User.username == robot_name, User.robot == True))
|
||||
|
||||
def convert_user_to_organization(user, admin_user):
|
||||
# Change the user to an organization.
|
||||
|
|
|
@ -7,6 +7,7 @@ from auth.permissions import AdministerOrganizationPermission
|
|||
from auth.auth_context import get_authenticated_user
|
||||
from auth import scopes
|
||||
from data import model
|
||||
from app import avatar
|
||||
|
||||
|
||||
def prototype_view(proto, org_members):
|
||||
|
@ -16,6 +17,7 @@ def prototype_view(proto, org_members):
|
|||
'is_robot': user.robot,
|
||||
'kind': 'user',
|
||||
'is_org_member': user.robot or user.username in org_members,
|
||||
'avatar': avatar.get_data_for_user(user)
|
||||
}
|
||||
|
||||
if proto.delegate_user:
|
||||
|
@ -24,6 +26,7 @@ def prototype_view(proto, org_members):
|
|||
delegate_view = {
|
||||
'name': proto.delegate_team.name,
|
||||
'kind': 'team',
|
||||
'avatar': avatar.get_data_for_team(proto.delegate_team)
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -6,12 +6,24 @@ from auth.auth_context import get_authenticated_user
|
|||
from auth import scopes
|
||||
from data import model
|
||||
from util.names import format_robot_username
|
||||
from flask import abort
|
||||
|
||||
|
||||
def robot_view(name, token):
|
||||
def robot_view(name, token, count=None):
|
||||
return {
|
||||
'name': name,
|
||||
'token': token,
|
||||
'permission_count': count
|
||||
}
|
||||
|
||||
|
||||
def permission_view(permission):
|
||||
return {
|
||||
'repository': {
|
||||
'name': permission.repository.name,
|
||||
'is_public': permission.repository.visibility.name == 'public'
|
||||
},
|
||||
'role': permission.role.name
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +38,7 @@ class UserRobotList(ApiResource):
|
|||
user = get_authenticated_user()
|
||||
robots = model.list_entity_robot_tuples(user.username)
|
||||
return {
|
||||
'robots': [robot_view(name, password) for name, password in robots]
|
||||
'robots': [robot_view(name, password, count) for name, password, count in robots]
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +87,7 @@ class OrgRobotList(ApiResource):
|
|||
if permission.can():
|
||||
robots = model.list_entity_robot_tuples(orgname)
|
||||
return {
|
||||
'robots': [robot_view(name, password) for name, password in robots]
|
||||
'robots': [robot_view(name, password, count) for name, password, count in robots]
|
||||
}
|
||||
|
||||
raise Unauthorized()
|
||||
|
@ -125,6 +137,47 @@ class OrgRobot(ApiResource):
|
|||
raise Unauthorized()
|
||||
|
||||
|
||||
@resource('/v1/user/robots/<robot_shortname>/permissions')
|
||||
@path_param('robot_shortname', 'The short name for the robot, without any user or organization prefix')
|
||||
@internal_only
|
||||
class UserRobotPermissions(ApiResource):
|
||||
""" Resource for listing the permissions a user's robot has in the system. """
|
||||
@require_user_admin
|
||||
@nickname('getUserRobotPermissions')
|
||||
def get(self, robot_shortname):
|
||||
""" Returns the list of repository permissions for the user's robot. """
|
||||
parent = get_authenticated_user()
|
||||
robot, password = model.get_robot(robot_shortname, parent)
|
||||
permissions = model.list_robot_permissions(robot.username)
|
||||
|
||||
return {
|
||||
'permissions': [permission_view(permission) for permission in permissions]
|
||||
}
|
||||
|
||||
|
||||
@resource('/v1/organization/<orgname>/robots/<robot_shortname>/permissions')
|
||||
@path_param('orgname', 'The name of the organization')
|
||||
@path_param('robot_shortname', 'The short name for the robot, without any user or organization prefix')
|
||||
@related_user_resource(UserRobotPermissions)
|
||||
class OrgRobotPermissions(ApiResource):
|
||||
""" Resource for listing the permissions an org's robot has in the system. """
|
||||
@require_user_admin
|
||||
@nickname('getOrgRobotPermissions')
|
||||
def get(self, orgname, robot_shortname):
|
||||
""" Returns the list of repository permissions for the org's robot. """
|
||||
permission = AdministerOrganizationPermission(orgname)
|
||||
if permission.can():
|
||||
parent = model.get_organization(orgname)
|
||||
robot, password = model.get_robot(robot_shortname, parent)
|
||||
permissions = model.list_robot_permissions(robot.username)
|
||||
|
||||
return {
|
||||
'permissions': [permission_view(permission) for permission in permissions]
|
||||
}
|
||||
|
||||
abort(403)
|
||||
|
||||
|
||||
@resource('/v1/user/robots/<robot_shortname>/regenerate')
|
||||
@path_param('robot_shortname', 'The short name for the robot, without any user or organization prefix')
|
||||
@internal_only
|
||||
|
|
|
@ -175,8 +175,8 @@ class User(ApiResource):
|
|||
'description': 'The user\'s email address',
|
||||
},
|
||||
'avatar': {
|
||||
'type': 'string',
|
||||
'description': 'Avatar hash representing the user\'s icon'
|
||||
'type': 'object',
|
||||
'description': 'Avatar data representing the user\'s icon'
|
||||
},
|
||||
'organizations': {
|
||||
'type': 'array',
|
||||
|
|
|
@ -818,6 +818,17 @@
|
|||
width: 30px;
|
||||
}
|
||||
|
||||
.co-table td.caret-col {
|
||||
width: 10px;
|
||||
padding-left: 6px;
|
||||
padding-right: 0px;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.co-table td.caret-col i.fa {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.co-table .add-row-spacer td {
|
||||
padding: 5px;
|
||||
}
|
||||
|
|
86
static/css/directives/ui/robots-manager.css
Normal file
86
static/css/directives/ui/robots-manager.css
Normal file
|
@ -0,0 +1,86 @@
|
|||
.robots-manager-element .manager-header {
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.robots-manager-element .manager-header h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.robots-manager-element .robot a {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.robots-manager-element .robot .prefix {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.robots-manager-element .robot i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.robots-manager-element .popup-input-button i.fa {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.robots-manager-element .empty {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.robots-manager-element tr.open td {
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
.robots-manager-element .permissions-table-wrapper {
|
||||
margin-left: 0px;
|
||||
border-left: 2px solid #ccc;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.robots-manager-element .permissions-table tbody tr:last-child td {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
.robots-manager-element .permissions-display-row {
|
||||
position: relative;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.robots-manager-element .permissions-display-row td:first-child {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.robots-manager-element .repo-circle {
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
background: #eee;
|
||||
padding: 4px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.robots-manager-element .repo-circle .fa-hdd-o {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.robots-manager-element .repo-circle.no-background .fa-hdd-o {
|
||||
font-size: 1.7em;
|
||||
}
|
||||
|
||||
.robots-manager-element .repo-circle .fa-lock {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.robots-manager-element .repo-circle.no-background .fa-lock {
|
||||
bottom: 5px;
|
||||
right: 2px;
|
||||
}
|
|
@ -6,4 +6,20 @@
|
|||
.org-view h3 {
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.org-view .section-description-header {
|
||||
padding-left: 40px;
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.org-view .section-description-header:before {
|
||||
font-family: FontAwesome;
|
||||
content: "\f05a";
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 6px;
|
||||
font-size: 27px;
|
||||
color: #888;
|
||||
}
|
|
@ -525,27 +525,6 @@ i.toggle-icon:hover {
|
|||
visibility: hidden;
|
||||
}
|
||||
|
||||
.robots-manager-element {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.robots-manager-element .alert {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.robots-manager-element .robot a {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.robots-manager-element .robot .prefix {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.robots-manager-element .robot i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.logs-view-element .header {
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
|
|
@ -1,32 +1,102 @@
|
|||
<div class="robots-manager-element">
|
||||
<div class="quay-spinner" ng-show="loading"></div>
|
||||
<div class="alert alert-info">Robot accounts allow for delegating access in multiple repositories to role-based accounts that you manage</div>
|
||||
<div class="cor-loader" ng-show="loading"></div>
|
||||
|
||||
<div ng-show="!loading">
|
||||
<div class="side-controls">
|
||||
<span class="popup-input-button" pattern="ROBOT_PATTERN" placeholder="'Robot Account Name'"
|
||||
submitted="createRobot(value)">
|
||||
<i class="fa fa-wrench"></i> Create Robot Account
|
||||
</span>
|
||||
<div class="manager-header">
|
||||
<div class="side-controls">
|
||||
<span class="popup-input-button" pattern="ROBOT_PATTERN"
|
||||
placeholder="'Robot Account Name'"
|
||||
submitted="createRobot(value)">
|
||||
<i class="fa fa-plus"></i> Create Robot Account
|
||||
</span>
|
||||
</div>
|
||||
<h3>Robot Accounts</h3>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
<div class="manager-header section-description-header">
|
||||
Robot Accounts are named tokens that can be granted permissions on multiple repositories
|
||||
under this <span ng-if="organization">organization</span><span ng-if="!organization">user namespace</span>. They are typically used in environments where credentials will
|
||||
be shared, such as deployment systems.
|
||||
</div>
|
||||
|
||||
<div class="empty" ng-if="!robots.length">
|
||||
<div class="empty-primary-msg">No robot accounts defined.</div>
|
||||
<div class="empty-secondary-msg">
|
||||
Click the "Create Robot Account" button above to create a robot account.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="co-table" ng-if="robots.length">
|
||||
<thead>
|
||||
<th>Robot Account Name</th>
|
||||
<th style="width: 150px"></th>
|
||||
<td class="caret-col" ng-if="organization.is_admin"></td>
|
||||
<td>Robot Account Name</td>
|
||||
<td>Repository Permissions</td>
|
||||
<td class="options-col"></td>
|
||||
</thead>
|
||||
|
||||
<tr ng-repeat="robotInfo in robots">
|
||||
<td class="robot">
|
||||
<i class="fa fa-wrench"></i>
|
||||
<a ng-click="showRobot(robotInfo)">
|
||||
<span class="prefix">{{ getPrefix(robotInfo.name) }}+</span>{{ getShortenedName(robotInfo.name) }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="delete-ui" delete-title="'Delete Robot Account'" perform-delete="deleteRobot(robotInfo)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody ng-repeat="robotInfo in robots">
|
||||
<tr ng-class="robotInfo.showing_permissions ? 'open' : 'closed'">
|
||||
<td class="caret-col" ng-if="organization.is_admin">
|
||||
<span ng-if="robotInfo.permission_count > 0" ng-click="showPermissions(robotInfo)">
|
||||
<i class="fa"
|
||||
ng-class="robotInfo.showing_permissions ? 'fa-caret-down' : 'fa-caret-right'"
|
||||
data-title="View Permissions List" bs-tooltip></i>
|
||||
</span>
|
||||
</td>
|
||||
<td class="robot">
|
||||
<i class="fa fa-wrench"></i>
|
||||
<a ng-click="showRobot(robotInfo)">
|
||||
<span class="prefix">{{ getPrefix(robotInfo.name) }}+</span>{{ getShortenedName(robotInfo.name) }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="empty" ng-if="robotInfo.permission_count == 0">(No permissions on any repositories)</span>
|
||||
<span ng-if="robotInfo.permission_count > 0">
|
||||
Permissions on
|
||||
<span class="anchor" href="javascript:void(0)" is-text-only="!organization.is_admin" ng-click="showPermissions(robotInfo)">{{ robotInfo.permission_count }}
|
||||
<span ng-if="robotInfo.permission_count == 1">repository</span>
|
||||
<span ng-if="robotInfo.permission_count > 1">repositories</span>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
<td class="options-col">
|
||||
<span class="cor-options-menu">
|
||||
<span class="cor-option" option-click="showRobot(robotInfo)">
|
||||
<i class="fa fa-key"></i> View Credentials
|
||||
</span>
|
||||
<span class="cor-option" option-click="deleteRobot(robotInfo)">
|
||||
<i class="fa fa-times"></i> Delete Robot {{ robotInfo.name }}
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="robotInfo.showing_permissions">
|
||||
<td class="permissions-display-row" colspan="4">
|
||||
<span class="cor-loader" ng-if="robotInfo.loading_permissions"></span>
|
||||
<div class="permissions-table-wrapper">
|
||||
<table class="permissions-table" ng-if="!robotInfo.loading_permissions">
|
||||
<thead>
|
||||
<td>Repository</td>
|
||||
<td>Permission</td>
|
||||
</thead>
|
||||
|
||||
<tr ng-repeat="permission in robotInfo.permissions">
|
||||
<td>
|
||||
<span class="repo-icon repo-circle no-background" repo="permission.repository"></span>
|
||||
<a ng-href="/repository/{{ getPrefix(robotInfo.name) }}/{{ permission.repository.name }}">{{ getPrefix(robotInfo.name) }}/{{ permission.repository.name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<span class="role-group" current-role="permission.role" roles="roles"
|
||||
read-only="true"></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<div class="btn-group btn-group-sm">
|
||||
<button ng-repeat="role in roles"
|
||||
type="button" class="btn" ng-click="setRole(role.id)"
|
||||
ng-class="(currentRole == role.id) ? ('active btn-' + role.kind) : 'btn-default'">{{ role.title }}</button>
|
||||
ng-class="(currentRole == role.id) ? ('active btn-' + role.kind) : 'btn-default'"
|
||||
ng-disabled="readOnly">{{ role.title }}</button>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,7 @@ angular.module('quay').directive('repositoryPermissionsTable', function () {
|
|||
'repository': '=repository'
|
||||
},
|
||||
controller: function($scope, $element, ApiService, Restangular, UtilService) {
|
||||
// TODO(jschorr): move this to a service.
|
||||
$scope.roles = [
|
||||
{ 'id': 'read', 'title': 'Read', 'kind': 'success' },
|
||||
{ 'id': 'write', 'title': 'Write', 'kind': 'success' },
|
||||
|
|
|
@ -14,11 +14,36 @@ angular.module('quay').directive('robotsManager', function () {
|
|||
},
|
||||
controller: function($scope, $element, ApiService, $routeParams, CreateService) {
|
||||
$scope.ROBOT_PATTERN = ROBOT_PATTERN;
|
||||
|
||||
// TODO(jschorr): move this to a service.
|
||||
$scope.roles = [
|
||||
{ 'id': 'read', 'title': 'Read', 'kind': 'success' },
|
||||
{ 'id': 'write', 'title': 'Write', 'kind': 'success' },
|
||||
{ 'id': 'admin', 'title': 'Admin', 'kind': 'primary' }
|
||||
];
|
||||
|
||||
$scope.robots = null;
|
||||
$scope.loading = false;
|
||||
$scope.shownRobot = null;
|
||||
$scope.showRobotCounter = 0;
|
||||
|
||||
var loadRobotPermissions = function(info) {
|
||||
var shortName = $scope.getShortenedName(info.name);
|
||||
info.loading_permissions = true;
|
||||
ApiService.getRobotPermissions($scope.organization, null, {'robot_shortname': shortName}).then(function(resp) {
|
||||
info.permissions = resp.permissions;
|
||||
info.loading_permissions = false;
|
||||
}, ApiService.errorDisplay('Could not load robot permissions'));
|
||||
};
|
||||
|
||||
$scope.showPermissions = function(robotInfo) {
|
||||
robotInfo.showing_permissions = !robotInfo.showing_permissions;
|
||||
|
||||
if (robotInfo.showing_permissions) {
|
||||
loadRobotPermissions(robotInfo);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.regenerateToken = function(username) {
|
||||
if (!username) { return; }
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ angular.module('quay').directive('roleGroup', function () {
|
|||
scope: {
|
||||
'roles': '=roles',
|
||||
'currentRole': '=currentRole',
|
||||
'readOnly': '=readOnly',
|
||||
'roleChanged': '&roleChanged'
|
||||
},
|
||||
controller: function($scope, $element) {
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
<span class="cor-tab" tab-title="Teams" tab-target="#teams">
|
||||
<i class="fa fa-users"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Robot Accounts" tab-target="#robots" ng-if="isAdmin">
|
||||
<span class="cor-tab" tab-title="Robot Accounts" tab-target="#robots" ng-show="isAdmin">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Default Permissions" tab-target="#default" ng-if="isAdmin">
|
||||
<span class="cor-tab" tab-title="Default Permissions" tab-target="#default" ng-show="isAdmin">
|
||||
<i class="fa ci-stamp"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Billing" tab-target="#usage"
|
||||
|
@ -33,15 +33,15 @@
|
|||
<i class="fa ci-invoice"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Usage Logs" tab-target="#logs"
|
||||
tab-init="showLogs()" ng-if="isAdmin">
|
||||
tab-init="showLogs()" ng-show="isAdmin">
|
||||
<i class="fa fa-bar-chart"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Applications" tab-target="#applications"
|
||||
tab-init="showApplications()"ng-if="isAdmin">
|
||||
tab-init="showApplications()" ng-show="isAdmin">
|
||||
<i class="fa ci-application"></i>
|
||||
</span>
|
||||
<span class="cor-tab" tab-title="Organization Settings" tab-target="#settings"
|
||||
ng-if="isAdmin">
|
||||
ng-show="isAdmin">
|
||||
<i class="fa fa-gears"></i>
|
||||
</span>
|
||||
</div> <!-- /cor-tabs -->
|
||||
|
@ -65,7 +65,6 @@
|
|||
|
||||
<!-- Robot Accounts -->
|
||||
<div id="robots" class="tab-pane">
|
||||
<h3>Robot Accounts</h3>
|
||||
<div class="robots-manager" organization="organization"></div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@ from endpoints.api.image import RepositoryImageChanges, RepositoryImage, Reposit
|
|||
from endpoints.api.build import (FileDropResource, RepositoryBuildStatus, RepositoryBuildLogs,
|
||||
RepositoryBuildList, RepositoryBuildResource)
|
||||
from endpoints.api.robot import (UserRobotList, OrgRobot, OrgRobotList, UserRobot,
|
||||
RegenerateOrgRobot, RegenerateUserRobot)
|
||||
RegenerateOrgRobot, RegenerateUserRobot, UserRobotPermissions,
|
||||
OrgRobotPermissions)
|
||||
|
||||
from endpoints.api.trigger import (BuildTriggerActivate, BuildTriggerSources, BuildTriggerSubdirs,
|
||||
TriggerBuildList, ActivateBuildTrigger, BuildTrigger,
|
||||
|
@ -3335,10 +3336,28 @@ class TestRegenerateOrgRobot(ApiTestCase):
|
|||
self._run_test('POST', 400, 'devtable', None)
|
||||
|
||||
|
||||
class TestOrganizationBuynlarge(ApiTestCase):
|
||||
class TestUserRobotPermissions(ApiTestCase):
|
||||
def setUp(self):
|
||||
ApiTestCase.setUp(self)
|
||||
self._set_url(Organization, orgname="buynlarge")
|
||||
self._set_url(UserRobotPermissions, robot_shortname="robotname")
|
||||
|
||||
def test_get_anonymous(self):
|
||||
self._run_test('GET', 401, None, None)
|
||||
|
||||
def test_get_freshuser(self):
|
||||
self._run_test('GET', 400, 'freshuser', None)
|
||||
|
||||
def test_get_reader(self):
|
||||
self._run_test('GET', 400, 'reader', None)
|
||||
|
||||
def test_get_devtable(self):
|
||||
self._run_test('GET', 400, 'devtable', None)
|
||||
|
||||
|
||||
class TestOrgRobotPermissions(ApiTestCase):
|
||||
def setUp(self):
|
||||
ApiTestCase.setUp(self)
|
||||
self._set_url(OrgRobotPermissions, orgname="buynlarge", robot_shortname="robotname")
|
||||
|
||||
def test_get_anonymous(self):
|
||||
self._run_test('GET', 401, None, None)
|
||||
|
@ -3346,6 +3365,24 @@ class TestOrganizationBuynlarge(ApiTestCase):
|
|||
def test_get_freshuser(self):
|
||||
self._run_test('GET', 403, 'freshuser', None)
|
||||
|
||||
def test_get_reader(self):
|
||||
self._run_test('GET', 403, 'reader', None)
|
||||
|
||||
def test_get_devtable(self):
|
||||
self._run_test('GET', 400, 'devtable', None)
|
||||
|
||||
|
||||
class TestOrganizationBuynlarge(ApiTestCase):
|
||||
def setUp(self):
|
||||
ApiTestCase.setUp(self)
|
||||
self._set_url(Organization, orgname="buynlarge")
|
||||
|
||||
def test_get_anonymous(self):
|
||||
self._run_test('GET', 200, None, None)
|
||||
|
||||
def test_get_freshuser(self):
|
||||
self._run_test('GET', 200, 'freshuser', None)
|
||||
|
||||
def test_get_reader(self):
|
||||
self._run_test('GET', 200, 'reader', None)
|
||||
|
||||
|
|
|
@ -552,12 +552,12 @@ class TestGetOrganization(ApiTestCase):
|
|||
def test_unknownorg(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
self.getResponse(Organization, params=dict(orgname='notvalid'),
|
||||
expected_code=403)
|
||||
expected_code=404)
|
||||
|
||||
def test_cannotaccess(self):
|
||||
self.login(NO_ACCESS_USER)
|
||||
self.getResponse(Organization, params=dict(orgname=ORGANIZATION),
|
||||
expected_code=403)
|
||||
expected_code=200)
|
||||
|
||||
def test_getorganization(self):
|
||||
self.login(READ_ACCESS_USER)
|
||||
|
|
Reference in a new issue