diff --git a/endpoints/api/billing.py b/endpoints/api/billing.py index 89c94963b..f5b022ca6 100644 --- a/endpoints/api/billing.py +++ b/endpoints/api/billing.py @@ -4,10 +4,11 @@ from flask import request from app import billing from endpoints.api import (resource, nickname, ApiResource, validate_json_request, log_action, related_user_resource, internal_only, Unauthorized, NotFound, - require_user_admin, show_if, hide_if, path_param) + require_user_admin, show_if, hide_if, path_param, require_scope) from endpoints.api.subscribe import subscribe, subscription_view from auth.permissions import AdministerOrganizationPermission from auth.auth_context import get_authenticated_user +from auth import scopes from data import model from data.billing import PLANS @@ -158,6 +159,7 @@ class OrganizationCard(ApiResource): }, } + @require_scope(scopes.ORG_ADMIN) @nickname('getOrgCard') def get(self, orgname): """ Get the organization's credit card. """ @@ -270,6 +272,7 @@ class OrganizationPlan(ApiResource): }, } + @require_scope(scopes.ORG_ADMIN) @nickname('updateOrgSubscription') @validate_json_request('OrgSubscription') def put(self, orgname): @@ -284,6 +287,7 @@ class OrganizationPlan(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('getOrgSubscription') def get(self, orgname): """ Fetch any existing subscription for the org. """ @@ -326,11 +330,11 @@ class UserInvoiceList(ApiResource): @resource('/v1/organization//invoices') @path_param('orgname', 'The name of the organization') -@internal_only @related_user_resource(UserInvoiceList) @show_if(features.BILLING) class OrgnaizationInvoiceList(ApiResource): """ Resource for listing an orgnaization's invoices. """ + @require_scope(scopes.ORG_ADMIN) @nickname('listOrgInvoices') def get(self, orgname): """ List the invoices for the specified orgnaization. """ diff --git a/endpoints/api/logs.py b/endpoints/api/logs.py index 606c8b198..6a45a497f 100644 --- a/endpoints/api/logs.py +++ b/endpoints/api/logs.py @@ -5,10 +5,11 @@ from datetime import datetime, timedelta from endpoints.api import (resource, nickname, ApiResource, query_param, parse_args, RepositoryParamResource, require_repo_admin, related_user_resource, format_date, Unauthorized, NotFound, require_user_admin, - internal_only, path_param) + internal_only, path_param, require_scope) from auth.permissions import AdministerOrganizationPermission, AdministerOrganizationPermission from auth.auth_context import get_authenticated_user from data import model +from auth import scopes def log_view(log): @@ -64,7 +65,6 @@ def get_logs(start_time, end_time, performer_name=None, repository=None, namespa @resource('/v1/repository//logs') @path_param('repository', 'The full path of the repository. e.g. namespace/name') -@internal_only class RepositoryLogs(RepositoryParamResource): """ Resource for fetching logs for the specific repository. """ @require_repo_admin @@ -105,7 +105,6 @@ class UserLogs(ApiResource): @resource('/v1/organization//logs') @path_param('orgname', 'The name of the organization') -@internal_only @related_user_resource(UserLogs) class OrgLogs(ApiResource): """ Resource for fetching logs for the entire organization. """ @@ -114,6 +113,7 @@ class OrgLogs(ApiResource): @query_param('starttime', 'Earliest time from which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('endtime', 'Latest time to which to get logs. (%m/%d/%Y %Z)', type=str) @query_param('performer', 'Username for which to filter logs.', type=str) + @require_scope(scopes.ORG_ADMIN) def get(self, args, orgname): """ List the logs for the specified organization. """ permission = AdministerOrganizationPermission(orgname) diff --git a/endpoints/api/organization.py b/endpoints/api/organization.py index c4c870fec..83bd9f1ea 100644 --- a/endpoints/api/organization.py +++ b/endpoints/api/organization.py @@ -5,12 +5,14 @@ from flask import request from app import billing as stripe from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error, related_user_resource, internal_only, Unauthorized, NotFound, - require_user_admin, log_action, show_if, path_param) + require_user_admin, log_action, show_if, path_param, + require_scope) from endpoints.api.team import team_view from endpoints.api.user import User, PrivateRepositories from auth.permissions import (AdministerOrganizationPermission, OrganizationMemberPermission, CreateRepositoryPermission) from auth.auth_context import get_authenticated_user +from auth import scopes from data import model from data.billing import get_plan from util.gravatar import compute_hash @@ -98,7 +100,6 @@ class OrganizationList(ApiResource): @resource('/v1/organization/') @path_param('orgname', 'The name of the organization') -@internal_only @related_user_resource(User) class Organization(ApiResource): """ Resource for managing organizations. """ @@ -119,6 +120,8 @@ class Organization(ApiResource): }, }, } + + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganization') def get(self, orgname): """ Get the details for the specified organization """ @@ -134,6 +137,7 @@ class Organization(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('changeOrganizationDetails') @validate_json_request('UpdateOrg') def put(self, orgname): @@ -170,6 +174,8 @@ class Organization(ApiResource): @show_if(features.BILLING) class OrgPrivateRepositories(ApiResource): """ Custom verb to compute whether additional private repositories are available. """ + + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationPrivateAllowed') def get(self, orgname): """ Return whether or not this org is allowed to create new private repositories. """ @@ -202,9 +208,10 @@ class OrgPrivateRepositories(ApiResource): @resource('/v1/organization//members') @path_param('orgname', 'The name of the organization') -@internal_only class OrgnaizationMemberList(ApiResource): """ Resource for listing the members of an organization. """ + + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationMembers') def get(self, orgname): """ List the members of the specified organization. """ @@ -237,9 +244,10 @@ class OrgnaizationMemberList(ApiResource): @resource('/v1/organization//members/') @path_param('orgname', 'The name of the organization') @path_param('membername', 'The username of the organization member') -@internal_only class OrganizationMember(ApiResource): """ Resource for managing individual organization members. """ + + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationMember') def get(self, orgname, membername): """ Get information on the specific orgnaization member. """ @@ -273,6 +281,7 @@ class OrganizationMember(ApiResource): @path_param('client_id', 'The OAuth client ID') class ApplicationInformation(ApiResource): """ Resource that returns public information about a registered application. """ + @nickname('getApplicationInformation') def get(self, client_id): """ Get information on the specified application. """ @@ -309,7 +318,6 @@ def app_view(application): @resource('/v1/organization//applications') @path_param('orgname', 'The name of the organization') -@internal_only class OrganizationApplications(ApiResource): """ Resource for managing applications defined by an organizations. """ schemas = { @@ -345,7 +353,7 @@ class OrganizationApplications(ApiResource): }, } - + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationApplications') def get(self, orgname): """ List the applications for the specified organization """ @@ -361,6 +369,7 @@ class OrganizationApplications(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('createOrganizationApplication') @validate_json_request('NewApp') def post(self, orgname): @@ -395,7 +404,6 @@ class OrganizationApplications(ApiResource): @resource('/v1/organization//applications/') @path_param('orgname', 'The name of the organization') @path_param('client_id', 'The OAuth client ID') -@internal_only class OrganizationApplicationResource(ApiResource): """ Resource for managing an application defined by an organizations. """ schemas = { @@ -433,6 +441,7 @@ class OrganizationApplicationResource(ApiResource): }, } + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationApplication') def get(self, orgname, client_id): """ Retrieves the application with the specified client_id under the specified organization """ @@ -451,6 +460,7 @@ class OrganizationApplicationResource(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('updateOrganizationApplication') @validate_json_request('UpdateApp') def put(self, orgname, client_id): @@ -484,7 +494,7 @@ class OrganizationApplicationResource(ApiResource): return app_view(application) raise Unauthorized() - + @require_scope(scopes.ORG_ADMIN) @nickname('deleteOrganizationApplication') def delete(self, orgname, client_id): """ Deletes the application under this organization. """ diff --git a/endpoints/api/prototype.py b/endpoints/api/prototype.py index 8e43bbf42..d4d736d2c 100644 --- a/endpoints/api/prototype.py +++ b/endpoints/api/prototype.py @@ -1,9 +1,11 @@ from flask import request from endpoints.api import (resource, nickname, ApiResource, validate_json_request, request_error, - log_action, Unauthorized, NotFound, internal_only, path_param) + log_action, Unauthorized, NotFound, internal_only, path_param, + require_scope) from auth.permissions import AdministerOrganizationPermission from auth.auth_context import get_authenticated_user +from auth import scopes from data import model @@ -55,7 +57,6 @@ def log_prototype_action(action_kind, orgname, prototype, **kwargs): @resource('/v1/organization//prototypes') @path_param('orgname', 'The name of the organization') -@internal_only class PermissionPrototypeList(ApiResource): """ Resource for listing and creating permission prototypes. """ schemas = { @@ -116,6 +117,7 @@ class PermissionPrototypeList(ApiResource): }, } + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationPrototypePermissions') def get(self, orgname): """ List the existing prototypes for this organization. """ @@ -132,6 +134,7 @@ class PermissionPrototypeList(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('createOrganizationPrototypePermission') @validate_json_request('NewPrototype') def post(self, orgname): @@ -182,7 +185,6 @@ class PermissionPrototypeList(ApiResource): @resource('/v1/organization//prototypes/') @path_param('orgname', 'The name of the organization') @path_param('prototypeid', 'The ID of the prototype') -@internal_only class PermissionPrototype(ApiResource): """ Resource for managingin individual permission prototypes. """ schemas = { @@ -207,6 +209,7 @@ class PermissionPrototype(ApiResource): }, } + @require_scope(scopes.ORG_ADMIN) @nickname('deleteOrganizationPrototypePermission') def delete(self, orgname, prototypeid): """ Delete an existing permission prototype. """ @@ -227,6 +230,7 @@ class PermissionPrototype(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('updateOrganizationPrototypePermission') @validate_json_request('PrototypeUpdate') def put(self, orgname, prototypeid): diff --git a/endpoints/api/team.py b/endpoints/api/team.py index bfbeae650..4ecef0e6e 100644 --- a/endpoints/api/team.py +++ b/endpoints/api/team.py @@ -31,7 +31,6 @@ def member_view(member): @resource('/v1/organization//team/') @path_param('orgname', 'The name of the organization') @path_param('teamname', 'The name of the team') -@internal_only class OrganizationTeam(ApiResource): """ Resource for manging an organization's teams. """ schemas = { @@ -60,6 +59,7 @@ class OrganizationTeam(ApiResource): }, } + @require_scope(scopes.ORG_ADMIN) @nickname('updateOrganizationTeam') @validate_json_request('TeamDescription') def put(self, orgname, teamname): @@ -101,6 +101,7 @@ class OrganizationTeam(ApiResource): raise Unauthorized() + @require_scope(scopes.ORG_ADMIN) @nickname('deleteOrganizationTeam') def delete(self, orgname, teamname): """ Delete the specified team. """ @@ -116,9 +117,10 @@ class OrganizationTeam(ApiResource): @resource('/v1/organization//team//members') @path_param('orgname', 'The name of the organization') @path_param('teamname', 'The name of the team') -@internal_only class TeamMemberList(ApiResource): """ Resource for managing the list of members for a team. """ + + @require_scope(scopes.ORG_ADMIN) @nickname('getOrganizationTeamMembers') def get(self, orgname, teamname): """ Retrieve the list of members for the specified team. """ @@ -147,6 +149,7 @@ class TeamMemberList(ApiResource): @path_param('membername', 'The username of the team member') class TeamMember(ApiResource): """ Resource for managing individual members of a team. """ + @require_scope(scopes.ORG_ADMIN) @nickname('updateOrganizationTeamMember') def put(self, orgname, teamname, membername): diff --git a/endpoints/api/trigger.py b/endpoints/api/trigger.py index 857b5116d..4cc224a00 100644 --- a/endpoints/api/trigger.py +++ b/endpoints/api/trigger.py @@ -145,7 +145,6 @@ class BuildTriggerSubdirs(RepositoryParamResource): @resource('/v1/repository//trigger//activate') @path_param('repository', 'The full path of the repository. e.g. namespace/name') @path_param('trigger_uuid', 'The UUID of the build trigger') -@internal_only class BuildTriggerActivate(RepositoryParamResource): """ Custom verb for activating a build trigger once all required information has been collected. """