def post(self, kid): if SuperUserPermission().can(): notes = request.get_json().get("notes", "") approver = get_authenticated_user() try: key = pre_oci_model.approve_service_key( kid, approver, ServiceKeyApprovalType.SUPERUSER, notes=notes ) # Log the approval of the service key. key_log_metadata = { "kid": kid, "service": key.service, "name": key.name, "expiration_date": key.expiration_date, } log_action("service_key_approve", None, key_log_metadata) except ServiceKeyDoesNotExist: raise NotFound() except ServiceKeyAlreadyApproved: pass return make_response("", 201) raise Unauthorized()
def delete(self, namespace_name, repository_name, manifestref, labelid): """ Deletes an existing label from a manifest. """ repo_ref = registry_model.lookup_repository(namespace_name, repository_name) if repo_ref is None: raise NotFound() manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref) if manifest is None: raise NotFound() deleted = registry_model.delete_manifest_label(manifest, labelid) if deleted is None: raise NotFound() metadata = { "id": labelid, "key": deleted.key, "value": deleted.value, "manifest_digest": manifestref, "namespace": namespace_name, "repo": repository_name, } log_action("manifest_label_delete", namespace_name, metadata, repo_name=repository_name) return "", 204
def post(self): """ Convert the user to an organization. """ user = get_authenticated_user() convert_data = request.get_json() # Ensure that the sign in credentials work. admin_username = convert_data["adminUser"] admin_password = convert_data["adminPassword"] (admin_user, _) = authentication.verify_and_link_user(admin_username, admin_password) if not admin_user: raise request_error( reason="invaliduser", message="The admin user credentials are not valid" ) # Ensure that the new admin user is the not user being converted. if admin_user.id == user.id: raise request_error(reason="invaliduser", message="The admin user is not valid") # Subscribe the organization to the new plan. if features.BILLING: plan = convert_data.get("plan", "free") subscribe(user, plan, None, True) # Require business plans # Convert the user to an organization. model.organization.convert_user_to_organization(user, admin_user) log_action("account_convert", user.username) # And finally login with the admin credentials. return conduct_signin(admin_username, admin_password)
def delete(self, namespace_name, repo_name, trigger_uuid): """ Delete the specified build trigger. """ trigger = get_trigger(trigger_uuid) handler = BuildTriggerHandler.get_handler(trigger) if handler.is_active(): try: handler.deactivate() except TriggerException as ex: # We are just going to eat this error logger.warning("Trigger deactivation problem: %s", ex) log_action( "delete_repo_trigger", namespace_name, {"repo": repo_name, "trigger_id": trigger_uuid, "service": trigger.service.name}, repo=model.repository.get_repository(namespace_name, repo_name), ) trigger.delete_instance(recursive=True) if trigger.write_token is not None: trigger.write_token.delete_instance() return "No Content", 204
def post(self, namespace): """ Takes ownership of the specified organization or user. """ if SuperUserPermission().can(): # Disallow for superusers. if superusers.is_superuser(namespace): raise InvalidRequest("Cannot take ownership of a superuser") authed_user = get_authenticated_user() entity_id, was_user = pre_oci_model.take_ownership(namespace, authed_user) if entity_id is None: raise NotFound() # Log the change. log_metadata = { "entity_id": entity_id, "namespace": namespace, "was_user": was_user, "superuser": authed_user.username, } log_action("take_ownership", authed_user.username, log_metadata) return jsonify({"namespace": namespace}) 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, 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, repository_name, uuid): """ Resets repository notification to 0 failures. """ reset = model.reset_notification_number_of_failures(namespace_name, repository_name, uuid) if not reset: raise InvalidRequest( "No repository notification found for: %s, %s, %s" % (namespace_name, repository_name, uuid) ) log_action( "reset_repo_notification", namespace_name, { "repo": repository_name, "namespace": namespace_name, "notification_id": uuid, "event": reset.event_name, "method": reset.method_name, }, repo_name=repository_name, ) return "No Content", 204
def post(self, namespace_name, repository_name): parsed = request.get_json() method_handler = NotificationMethod.get_method(parsed["method"]) try: method_handler.validate(namespace_name, repository_name, parsed["config"]) except CannotValidateNotificationMethodException as ex: raise request_error(message=ex.message) new_notification = model.create_repo_notification( namespace_name, repository_name, parsed["event"], parsed["method"], parsed["config"], parsed["eventConfig"], parsed.get("title"), ) log_action( "add_repo_notification", namespace_name, { "repo": repository_name, "namespace": namespace_name, "notification_id": new_notification.uuid, "event": new_notification.event_name, "method": new_notification.method_name, }, repo_name=repository_name, ) return new_notification.to_dict(), 201
def put(self, namespace, repository): """ Change the state of a repository. """ if not model.repo_exists(namespace, repository): raise NotFound() values = request.get_json() state_name = values["state"] try: state = RepositoryState[state_name] except KeyError: state = None if state == RepositoryState.MIRROR and not features.REPO_MIRROR: return {"detail": "Unknown Repository State: %s" % state_name}, 400 if state is None: return {"detail": "%s is not a valid Repository state." % state_name}, 400 model.set_repository_state(namespace, repository, state) log_action( "change_repo_state", namespace, {"repo": repository, "namespace": namespace, "state_changed": state_name}, repo_name=repository, ) return {"success": True}
def delete(self, namespace_name, repository_name, uuid): """ Deletes the specified notification. """ deleted = model.delete_repo_notification(namespace_name, repository_name, uuid) if not deleted: raise InvalidRequest( "No repository notification found for: %s, %s, %s" % (namespace_name, repository_name, uuid) ) log_action( "delete_repo_notification", namespace_name, { "repo": repository_name, "namespace": namespace_name, "notification_id": uuid, "event": deleted.event_name, "method": deleted.method_name, }, repo_name=repository_name, ) return "No Content", 204
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, namespace, repository): """ Change the visibility of a repository. """ if not model.repo_exists(namespace, repository): raise NotFound() tags, _ = tuf_metadata_api.get_default_tags_with_expiration( namespace, repository) if tags and not tuf_metadata_api.delete_metadata( namespace, repository): raise DownstreamIssue("Unable to delete downstream trust metadata") values = request.get_json() model.set_trust(namespace, repository, values["trust_enabled"]) log_action( "change_repo_trust", namespace, { "repo": repository, "namespace": namespace, "trust_enabled": values["trust_enabled"] }, repo_name=repository, ) return {"success": True}
def put(self, namespace_name, repository_name, username): # Also needs to respond to post """ Update the perimssions for an existing repository. """ new_permission = request.get_json() logger.debug("Setting permission to: %s for user %s", new_permission["role"], username) try: perm = model.set_repo_permission_for_user(username, namespace_name, repository_name, new_permission["role"]) resp = perm.to_dict() except SaveException as ex: raise request_error(exception=ex) log_action( "change_repo_permission", namespace_name, { "username": username, "repo": repository_name, "namespace": namespace_name, "role": new_permission["role"], }, repo_name=repository_name, ) return resp, 200
def delete(self, namespace_name, repository_name, manifestref, labelid): """ Deletes an existing label from a manifest. """ repo_ref = registry_model.lookup_repository(namespace_name, repository_name) if repo_ref is None: raise NotFound() manifest = registry_model.lookup_manifest_by_digest( repo_ref, manifestref) if manifest is None: raise NotFound() deleted = registry_model.delete_manifest_label(manifest, labelid) if deleted is None: raise NotFound() metadata = { 'id': labelid, 'key': deleted.key, 'value': deleted.value, 'manifest_digest': manifestref, 'namespace': namespace_name, 'repo': repository_name, } log_action('manifest_label_delete', namespace_name, metadata, repo_name=repository_name) return '', 204
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 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 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 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 put(self, namespace, repository): """ Change the state of a repository. """ if not model.repo_exists(namespace, repository): raise NotFound() values = request.get_json() state_name = values['state'] try: state = RepositoryState[state_name] except KeyError: state = None if state == RepositoryState.MIRROR and not features.REPO_MIRROR: return {'detail': 'Unknown Repository State: %s' % state_name}, 400 if state is None: return { 'detail': '%s is not a valid Repository state.' % state_name }, 400 model.set_repository_state(namespace, repository, state) log_action('change_repo_state', namespace, { 'repo': repository, 'namespace': namespace, 'state_changed': state_name }, repo_name=repository) return {'success': True}
def put(self, namespace_name, repo_name, trigger_uuid): """ Updates the specified build trigger. """ trigger = get_trigger(trigger_uuid) handler = BuildTriggerHandler.get_handler(trigger) if not handler.is_active(): raise InvalidRequest("Cannot update an unactivated trigger") enable = request.get_json()["enabled"] model.build.toggle_build_trigger(trigger, enable) log_action( "toggle_repo_trigger", namespace_name, { "repo": repo_name, "trigger_id": trigger_uuid, "service": trigger.service.name, "enabled": enable, }, repo=model.repository.get_repository(namespace_name, repo_name), ) return trigger_view(trigger)
def post(self): """ Update the user's credit card. """ user = get_authenticated_user() token = request.get_json()['token'] response = set_card(user, token) log_action('account_change_cc', user.username) return response
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, namespace_name, repository_name, teamname): """ Update the existing team permission. """ new_permission = request.get_json() logger.debug("Setting permission to: %s for team %s", new_permission["role"], teamname) try: perm = model.set_repo_permission_for_team(teamname, namespace_name, repository_name, new_permission["role"]) resp = perm.to_dict() except SaveException as ex: raise request_error(exception=ex) log_action( "change_repo_permission", namespace_name, { "team": teamname, "repo": repository_name, "role": new_permission["role"] }, repo_name=repository_name, ) return resp, 200
def post(self, namespace_name, repository_name, manifestref): """ Adds a new label into the tag manifest. """ label_data = request.get_json() # Check for any reserved prefixes. if label_validator.has_reserved_prefix(label_data['key']): abort(400, message='Label has a reserved prefix') repo_ref = registry_model.lookup_repository(namespace_name, repository_name) if repo_ref is None: raise NotFound() manifest = registry_model.lookup_manifest_by_digest( repo_ref, manifestref) if manifest is None: raise NotFound() label = None try: label = registry_model.create_manifest_label( manifest, label_data['key'], label_data['value'], 'api', label_data['media_type']) except InvalidLabelKeyException: message = ('Label is of an invalid format or missing please ' + 'use %s format for labels' % VALID_LABEL_KEY_REGEX) abort(400, message=message) except InvalidMediaTypeException: message = 'Media type is invalid please use a valid media type: text/plain, application/json' abort(400, message=message) if label is None: raise NotFound() metadata = { 'id': label.uuid, 'key': label.key, 'value': label.value, 'manifest_digest': manifestref, 'media_type': label.media_type_name, 'namespace': namespace_name, 'repo': repository_name, } log_action('manifest_label_add', namespace_name, metadata, repo_name=repository_name) resp = {'label': _label_dict(label)} repo_string = '%s/%s' % (namespace_name, repository_name) headers = { 'Location': api.url_for(ManageRepositoryManifestLabel, repository=repo_string, manifestref=manifestref, labelid=label.uuid), } return resp, 201, headers
def delete(self, robot_shortname): """ Delete an existing robot. """ parent = get_authenticated_user() model.delete_robot(format_robot_username(parent.username, robot_shortname)) log_action("delete_robot", parent.username, {"robot": robot_shortname}) return "", 204
def post(self, robot_shortname): """ Regenerates the token for a user's robot. """ parent = get_authenticated_user() robot = model.regenerate_user_robot_token(robot_shortname, parent) log_action("regenerate_robot_token", parent.username, {"robot": robot_shortname}) return robot.to_dict(include_token=True)
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 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()