def wrapped(self, *args, **kwargs): user = get_authenticated_user() if not user: raise Unauthorized() logger.debug("Checking permission %s for user %s", permission_class, user.username) permission = permission_class(user.username) if permission.can(): return func(self, *args, **kwargs) raise Unauthorized()
def delete(self, orgname, teamname, email): """ Delete an invite of an email address to join a team. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): team = None # Find the team. try: team = model.team.get_organization_team(orgname, teamname) except model.InvalidTeamException: raise NotFound() # Delete the invite. if not model.team.delete_team_email_invite(team, email): raise NotFound() log_action( "org_delete_team_member_invite", orgname, { "email": email, "team": teamname, "member": email }, ) return "", 204 raise Unauthorized()
def put(self, orgname, prototypeid): """ Update the role of an existing permission prototype. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() existing = model.permission.get_prototype_permission(org, prototypeid) if not existing: raise NotFound() details = request.get_json() role_name = details["role"] prototype = model.permission.update_prototype_permission(org, prototypeid, role_name) if not prototype: raise NotFound() log_prototype_action( "modify_prototype_permission", orgname, prototype, original_role=existing.role.name ) users_filter = {prototype.activating_user, prototype.delegate_user} org_members = model.organization.get_organization_member_set( org, users_filter=users_filter ) return prototype_view(prototype, org_members) raise Unauthorized()
def post(self, orgname): """ Create a new organization quota. """ if not SuperUserPermission().can(): raise Unauthorized() quota_data = request.get_json() limit_bytes = quota_data["limit_bytes"] try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() # Currently only supporting one quota definition per namespace quotas = model.namespacequota.get_namespace_quota_list(orgname) if quotas: raise request_error( message="Organization quota for '%s' already exists" % orgname) try: model.namespacequota.create_namespace_quota(org, limit_bytes) return "Created", 201 except model.DataModelException as ex: raise request_error(exception=ex)
def put(self, orgname, robot_shortname): """ Create a new robot in the organization. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): create_data = request.get_json() or {} robot = model.create_org_robot( robot_shortname, orgname, create_data.get("description"), create_data.get("unstructured_metadata"), ) log_action( "create_robot", orgname, { "robot": robot_shortname, "description": create_data.get("description"), "unstructured_metadata": create_data.get("unstructured_metadata"), }, ) return robot.to_dict(include_metadata=True, include_token=True), 201 raise Unauthorized()
def put(self, orgname, client_id): """ Updates an application under this organization. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() application = model.oauth.lookup_application(org, client_id) if not application: raise NotFound() app_data = request.get_json() application.name = app_data["name"] application.application_uri = app_data["application_uri"] application.redirect_uri = app_data["redirect_uri"] application.description = app_data.get("description", "") application.avatar_email = app_data.get("avatar_email", None) application.save() app_data.update({ "application_name": application.name, "client_id": application.client_id }) log_action("update_application", orgname, app_data) return app_view(application) raise Unauthorized()
def post(self, orgname): permission = AdministerOrganizationPermission(orgname) if not permission.can(): raise Unauthorized() try: model.proxy_cache.get_proxy_cache_config_for_org(orgname) request_error("Proxy Cache Configuration already exists") except model.InvalidProxyCacheConfigException: pass data = request.get_json() # filter None values data = {k: v for k, v in data.items() if v is not None} try: config = ProxyCacheConfig(**data) existing = model.organization.get_organization(orgname) config.organization = existing proxy = Proxy(config, "something-totally-fake", True) response = proxy.get(f"{proxy.base_url}/v2/") if response.status_code == 200: return "Valid", 202 except UpstreamRegistryError as e: raise request_error( message= "Failed login to remote registry. Please verify entered details and try again." ) raise request_error( message="Failed to validate Proxy cache configuration")
def get(self, orgname): """ Return whether or not this org is allowed to create new private repositories. """ permission = CreateRepositoryPermission(orgname) if permission.can(): organization = model.organization.get_organization(orgname) private_repos = model.user.get_private_repo_count( organization.username) data = {"privateAllowed": False} if organization.stripe_id: cus = stripe.Customer.retrieve(organization.stripe_id) if cus.subscription: repos_allowed = 0 plan = get_plan(cus.subscription.plan.id) if plan: repos_allowed = plan["privateRepos"] data["privateAllowed"] = private_repos < repos_allowed if AdministerOrganizationPermission(orgname).can(): data["privateCount"] = private_repos return data raise Unauthorized()
def post(self, orgname): """ Creates a new application under this organization. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() app_data = request.get_json() application = model.oauth.create_application( org, app_data["name"], app_data.get("application_uri", ""), app_data.get("redirect_uri", ""), description=app_data.get("description", ""), avatar_email=app_data.get("avatar_email", None), ) app_data.update({ "application_name": application.name, "client_id": application.client_id }) log_action("create_application", orgname, app_data) return app_view(application) raise Unauthorized()
def post(self, orgname): """ Creates proxy cache configuration for the organization. """ permission = AdministerOrganizationPermission(orgname) if not permission.can(): raise Unauthorized() try: model.proxy_cache.get_proxy_cache_config_for_org(orgname) raise request_error("Proxy Cache Configuration already exists") except model.InvalidProxyCacheConfigException: pass data = request.get_json() # filter None values data = {k: v for k, v in data.items() if (v is not None or not "")} try: config = model.proxy_cache.create_proxy_cache_config(**data) if config is not None: return "Created", 201 except model.DataModelException as e: logger.error( "Error while creating Proxy cache configuration as: %s", str(e)) return request_error("Error while creating Proxy cache configuration")
def post(self, orgname, client_id): """ Resets the client secret of the application. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() application = model.oauth.lookup_application(org, client_id) if not application: raise NotFound() application = model.oauth.reset_client_secret(application) log_action( "reset_application_client_secret", orgname, { "application_name": application.name, "client_id": client_id }, ) return app_view(application) raise Unauthorized()
def post(self, namespace_name, repo_name, trigger_uuid): """ List the subdirectories available for the specified build trigger and source. """ trigger = get_trigger(trigger_uuid) user_permission = UserAdminPermission(trigger.connected_user.username) if user_permission.can(): new_config_dict = request.get_json() handler = BuildTriggerHandler.get_handler(trigger, new_config_dict) try: subdirs = handler.list_build_subdirs() context_map = {} for file in subdirs: context_map = handler.get_parent_directory_mappings(file, context_map) return { "dockerfile_paths": ["/" + subdir for subdir in subdirs], "contextMap": context_map, "status": "success", } except EmptyRepositoryException as exc: return { "status": "success", "contextMap": {}, "dockerfile_paths": [], } except TriggerException as exc: return { "status": "error", "message": exc.message, } else: raise Unauthorized()
def put(self, orgname, teamname, email): """ Invites an email address to an existing team. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): team = None # Find the team. try: team = model.team.get_organization_team(orgname, teamname) except model.InvalidTeamException: raise NotFound() # Invite the email to the team. inviter = get_authenticated_user() invite = handle_addinvite_team(inviter, team, email=email) log_action( "org_invite_team_member", orgname, { "email": email, "team": teamname, "member": email }, ) return invite_view(invite) raise Unauthorized()
def delete(self, orgname, client_id): """ Deletes the application under this organization. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() application = model.oauth.delete_application(org, client_id) if not application: raise NotFound() log_action( "delete_application", orgname, { "application_name": application.name, "client_id": client_id }, ) return "", 204 raise Unauthorized()
def get(self, orgname): """ List the existing prototypes for this organization. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() permissions = model.permission.get_prototype_permissions(org) users_filter = {p.activating_user for p in permissions } | {p.delegate_user for p in permissions} org_members = model.organization.get_organization_member_set( org, users_filter=users_filter) return { "prototypes": [prototype_view(p, org_members) for p in permissions] } raise Unauthorized()
def post(self, orgname): """ Creates a new application under this organization. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() app_data = request.get_json() application = model.oauth.create_application( org, app_data['name'], app_data.get('application_uri', ''), app_data.get('redirect_uri', ''), description=app_data.get('description', ''), avatar_email=app_data.get('avatar_email', None)) app_data.update({ 'application_name': application.name, 'client_id': application.client_id }) log_action('create_application', orgname, app_data) return app_view(application) raise Unauthorized()
def get(self, orgname): """ List outside collaborators of the specified organization. """ permission = AdministerOrganizationPermission(orgname) if not permission.can(): raise Unauthorized() try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() all_perms = model.permission.list_organization_member_permissions(org) membership = model.team.list_organization_members_by_teams(org) org_members = set(m.user.username for m in membership) collaborators = {} for perm in all_perms: username = perm.user.username # Only interested in non-member permissions. if username in org_members: continue if username not in collaborators: collaborators[username] = { "kind": "user", "name": username, "avatar": avatar.get_data_for_user(perm.user), "repositories": [], } collaborators[username]["repositories"].append(perm.repository.name) return {"collaborators": collaborators.values()}
def post(self, orgname, quota_id): if not SuperUserPermission().can(): raise Unauthorized() quota_limit_data = request.get_json() quota_type = quota_limit_data["type"] quota_limit_threshold = quota_limit_data["threshold_percent"] quota = get_quota(orgname, quota_id) quota_limit = model.namespacequota.get_namespace_quota_limit_list( quota, quota_type=quota_type, percent_of_limit=quota_limit_threshold, ) if quota_limit: msg = "Quota limit already exists" raise request_error(message=msg) if quota_limit_data["type"].lower() == "reject" and quota_limit: raise request_error( message="Only one quota limit of type 'Reject' allowed.") try: model.namespacequota.create_namespace_quota_limit( quota, quota_type, quota_limit_threshold, ) return "Created", 201 except model.DataModelException as ex: raise request_error(exception=ex)
def get(self, orgname): """ Fetch any existing subscription for the org. """ cus = None permission = AdministerOrganizationPermission(orgname) if permission.can(): private_repos = model.user.get_private_repo_count(orgname) organization = model.organization.get_organization(orgname) if organization.stripe_id: try: cus = billing.Customer.retrieve(organization.stripe_id) except stripe.error.APIConnectionError as e: abort(503, message="Cannot contact Stripe") if cus.subscription: return subscription_view(cus.subscription, private_repos) return { "hasSubscription": False, "isExistingCustomer": cus is not None, "plan": "free", "usedPrivateRepos": private_repos, } raise Unauthorized()
def get(self, orgname, quota_id): orgperm = OrganizationMemberPermission(orgname) if not orgperm.can() and not SuperUserPermission().can(): raise Unauthorized() quota = get_quota(orgname, quota_id) return quota_view(quota)
def get(self, orgname): """ Get the organization's credit card. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): organization = model.organization.get_organization(orgname) return get_card(organization) raise Unauthorized()
def get(self, orgname, robot_shortname): """ Returns the organization's robot with the specified name. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): robot = model.get_org_robot(robot_shortname, orgname) return robot.to_dict(include_metadata=True, include_token=True) raise Unauthorized()
def post(self): """ Create a new repository. """ owner = get_authenticated_user() req = request.get_json() if owner is None and "namespace" not in "req": raise InvalidRequest( "Must provide a namespace or must be logged in.") namespace_name = req[ "namespace"] if "namespace" in req else owner.username permission = CreateRepositoryPermission(namespace_name) if permission.can(): repository_name = req["repository"] visibility = req["visibility"] if model.repo_exists(namespace_name, repository_name): raise request_error(message="Repository already exists") visibility = req["visibility"] if visibility == "private": check_allowed_private_repos(namespace_name) # Verify that the repository name is valid. if not REPOSITORY_NAME_REGEX.match(repository_name): raise InvalidRequest("Invalid repository name") kind = req.get("repo_kind", "image") or "image" created = model.create_repo( namespace_name, repository_name, owner, req["description"], visibility=visibility, repo_kind=kind, ) if created is None: raise InvalidRequest("Could not create repository") log_action( "create_repo", namespace_name, { "repo": repository_name, "namespace": namespace_name }, repo_name=repository_name, ) return { "namespace": namespace_name, "name": repository_name, "kind": kind, }, 201 raise Unauthorized()
def delete(self, orgname, robot_shortname): """ Delete an existing organization robot. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): model.delete_robot(format_robot_username(orgname, robot_shortname)) log_action("delete_robot", orgname, {"robot": robot_shortname}) return "", 204 raise Unauthorized()
def wrapped(self, namespace, repository, *args, **kwargs): logger.debug("Checking permission %s for repo: %s/%s", permission_class, namespace, repository) permission = permission_class(namespace, repository) if permission.can() or (allow_public and model.repository_is_public( namespace, repository)): return func(self, namespace, repository, *args, **kwargs) raise Unauthorized()
def get(self, orgname, teamname, parsed_args): """ Retrieve the list of members for the specified team. """ view_permission = ViewTeamPermission(orgname, teamname) edit_permission = AdministerOrganizationPermission(orgname) if view_permission.can(): team = None try: team = model.team.get_organization_team(orgname, teamname) except model.InvalidTeamException: raise NotFound() members = model.organization.get_organization_team_members(team.id) invites = [] if parsed_args["includePending"] and edit_permission.can(): invites = model.team.get_organization_team_member_invites( team.id) data = { "name": teamname, "members": [member_view(m) for m in members] + [invite_view(i) for i in invites], "can_edit": edit_permission.can(), } if features.TEAM_SYNCING and authentication.federated_service: if _syncing_setup_allowed(orgname): data["can_sync"] = { "service": authentication.federated_service, } data["can_sync"].update(authentication.service_metadata()) sync_info = model.team.get_team_sync_information( orgname, teamname) if sync_info is not None: data["synced"] = { "service": sync_info.service.name, } if SuperUserPermission().can(): data["synced"].update({ "last_updated": format_date(sync_info.last_updated), "config": json.loads(sync_info.config), }) return data raise Unauthorized()
def post(self, orgname, robot_shortname): """ Regenerates the token for an organization robot. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): robot = model.regenerate_org_robot_token(robot_shortname, orgname) log_action("regenerate_robot_token", orgname, {"robot": robot_shortname}) return robot.to_dict(include_token=True) raise Unauthorized()
def post(self, orgname): """ Create a new permission prototype. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): try: org = model.organization.get_organization(orgname) except model.InvalidOrganizationException: raise NotFound() details = request.get_json() activating_username = None if ( "activating_user" in details and details["activating_user"] and "name" in details["activating_user"] ): activating_username = details["activating_user"]["name"] delegate = details["delegate"] if "delegate" in details else {} delegate_kind = delegate.get("kind", None) delegate_name = delegate.get("name", None) delegate_username = delegate_name if delegate_kind == "user" else None delegate_teamname = delegate_name if delegate_kind == "team" else None activating_user = ( model.user.get_user(activating_username) if activating_username else None ) delegate_user = model.user.get_user(delegate_username) if delegate_username else None delegate_team = ( model.team.get_organization_team(orgname, delegate_teamname) if delegate_teamname else None ) if activating_username and not activating_user: raise request_error(message="Unknown activating user") if not delegate_user and not delegate_team: raise request_error(message="Missing delegate user or team") role_name = details["role"] prototype = model.permission.add_prototype_permission( org, role_name, activating_user, delegate_user, delegate_team ) log_prototype_action("create_prototype_permission", orgname, prototype) users_filter = {prototype.activating_user, prototype.delegate_user} org_members = model.organization.get_organization_member_set( org, users_filter=users_filter ) return prototype_view(prototype, org_members) raise Unauthorized()
def get(self, orgname, quota_id): orgperm = OrganizationMemberPermission(orgname) if not orgperm.can(): raise Unauthorized() quota = get_quota(orgname, quota_id) return [ limit_view(limit) for limit in model.namespacequota.get_namespace_quota_limit_list(quota) ]
def delete(self, orgname, teamname): """ Delete the specified team. """ permission = AdministerOrganizationPermission(orgname) if permission.can(): model.team.remove_team(orgname, teamname, get_authenticated_user().username) log_action("org_delete_team", orgname, {"team": teamname}) return "", 204 raise Unauthorized()