def _queue_logs_export(start_time, end_time, options, namespace_name, repository_name=None): callback_url = options.get("callback_url") if callback_url: if not callback_url.startswith( "https://") and not callback_url.startswith("http://"): raise InvalidRequest("Invalid callback URL") callback_email = options.get("callback_email") if callback_email: if callback_email.find("@") < 0: raise InvalidRequest("Invalid callback e-mail") (start_time, end_time) = _validate_logs_arguments(start_time, end_time) export_id = logs_model.queue_logs_export( start_time, end_time, export_action_logs_queue, namespace_name, repository_name, callback_url, callback_email, ) if export_id is None: raise InvalidRequest("Invalid export request") return export_id
def put(self, username): """ Updates information about the specified user. """ if SuperUserPermission().can(): user = pre_oci_model.get_nonrobot_user(username) if user is None: raise NotFound() if superusers.is_superuser(username): raise InvalidRequest('Cannot update a superuser') user_data = request.get_json() if 'password' in user_data: # Ensure that we are using database auth. if app.config['AUTHENTICATION_TYPE'] != 'Database': raise InvalidRequest( 'Cannot change password in non-database auth') pre_oci_model.change_password(username, user_data['password']) if 'email' in user_data: # Ensure that we are using database auth. if app.config['AUTHENTICATION_TYPE'] not in [ 'Database', 'AppToken' ]: raise InvalidRequest( 'Cannot change e-mail in non-database auth') pre_oci_model.update_email(username, user_data['email'], auto_verify=True) if 'enabled' in user_data: # Disable/enable the user. pre_oci_model.update_enabled(username, bool(user_data['enabled'])) if 'superuser' in user_data: config_object = config_provider.get_config() superusers_set = set(config_object['SUPER_USERS']) if user_data['superuser']: superusers_set.add(username) elif username in superusers_set: superusers_set.remove(username) config_object['SUPER_USERS'] = list(superusers_set) config_provider.save_config(config_object) return_value = user.to_dict() if user_data.get('password') is not None: password = user_data.get('password') return_value[ 'encrypted_password'] = authentication.encrypt_user_password( password) if user_data.get('email') is not None: return_value['email'] = user_data.get('email') return return_value raise Unauthorized()
def put(self, username): """ Updates information about the specified user. """ if SuperUserPermission().can(): user = pre_oci_model.get_nonrobot_user(username) if user is None: raise NotFound() if superusers.is_superuser(username): raise InvalidRequest("Cannot update a superuser") user_data = request.get_json() if "password" in user_data: # Ensure that we are using database auth. if app.config["AUTHENTICATION_TYPE"] != "Database": raise InvalidRequest("Cannot change password in non-database auth") pre_oci_model.change_password(username, user_data["password"]) if "email" in user_data: # Ensure that we are using database auth. if app.config["AUTHENTICATION_TYPE"] not in ["Database", "AppToken"]: raise InvalidRequest("Cannot change e-mail in non-database auth") pre_oci_model.update_email(username, user_data["email"], auto_verify=True) if "enabled" in user_data: # Disable/enable the user. pre_oci_model.update_enabled(username, bool(user_data["enabled"])) if "superuser" in user_data: config_object = config_provider.get_config() superusers_set = set(config_object["SUPER_USERS"]) if user_data["superuser"]: superusers_set.add(username) elif username in superusers_set: superusers_set.remove(username) config_object["SUPER_USERS"] = list(superusers_set) config_provider.save_config(config_object) return_value = user.to_dict() if user_data.get("password") is not None: password = user_data.get("password") return_value["encrypted_password"] = authentication.encrypt_user_password( password ).decode("ascii") if user_data.get("email") is not None: return_value["email"] = user_data.get("email") return return_value raise Unauthorized()
def put(self, kid): if SuperUserPermission().can(): body = request.get_json() try: key = pre_oci_model.get_service_key(kid, approved_only=False, alive_only=False) except ServiceKeyDoesNotExist: raise NotFound() key_log_metadata = { 'kid': key.kid, 'service': key.service, 'name': body.get('name', key.name), 'expiration_date': key.expiration_date, } if 'expiration' in body: expiration_date = body['expiration'] if expiration_date is not None and expiration_date != '': try: expiration_date = datetime.utcfromtimestamp( float(expiration_date)) except ValueError as ve: raise InvalidRequest('Invalid expiration date: %s' % ve) if expiration_date <= datetime.now(): raise InvalidRequest( 'Cannot have an expiration date in the past') key_log_metadata.update({ 'old_expiration_date': key.expiration_date, 'expiration_date': expiration_date, }) log_action('service_key_extend', None, key_log_metadata) pre_oci_model.set_key_expiration(kid, expiration_date) if 'name' in body or 'metadata' in body: key_name = body.get('name') if not validate_service_key_name(key_name): raise InvalidRequest( 'Invalid service key friendly name: %s' % key_name) pre_oci_model.update_service_key(kid, key_name, body.get('metadata')) log_action('service_key_modify', None, key_log_metadata) updated_key = pre_oci_model.get_service_key(kid, approved_only=False, alive_only=False) return jsonify(updated_key.to_dict()) raise Unauthorized()
def put(self, kid): if SuperUserPermission().can(): body = request.get_json() try: key = pre_oci_model.get_service_key(kid, approved_only=False, alive_only=False) except ServiceKeyDoesNotExist: raise NotFound() key_log_metadata = { "kid": key.kid, "service": key.service, "name": body.get("name", key.name), "expiration_date": key.expiration_date, } if "expiration" in body: expiration_date = body["expiration"] if expiration_date is not None and expiration_date != "": try: expiration_date = datetime.utcfromtimestamp( float(expiration_date)) except ValueError as ve: raise InvalidRequest("Invalid expiration date: %s" % ve) if expiration_date <= datetime.now(): raise InvalidRequest( "Cannot have an expiration date in the past") key_log_metadata.update({ "old_expiration_date": key.expiration_date, "expiration_date": expiration_date, }) log_action("service_key_extend", None, key_log_metadata) pre_oci_model.set_key_expiration(kid, expiration_date) if "name" in body or "metadata" in body: key_name = body.get("name") if not validate_service_key_name(key_name): raise InvalidRequest( "Invalid service key friendly name: %s" % key_name) pre_oci_model.update_service_key(kid, key_name, body.get("metadata")) log_action("service_key_modify", None, key_log_metadata) updated_key = pre_oci_model.get_service_key(kid, approved_only=False, alive_only=False) return jsonify(updated_key.to_dict()) 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 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): """ Creates a new user. """ # Ensure that we are using database auth. if app.config["AUTHENTICATION_TYPE"] != "Database": raise InvalidRequest("Cannot create a user in a non-database auth system") user_information = request.get_json() if SuperUserPermission().can(): # Generate a temporary password for the user. random = SystemRandom() password = "".join( [random.choice(string.ascii_uppercase + string.digits) for _ in range(32)] ) # Create the user. username = user_information["username"] email = user_information.get("email") install_user, confirmation_code = pre_oci_model.create_install_user( username, password, email ) if features.MAILING: send_confirmation_email( install_user.username, install_user.email, confirmation_code ) return { "username": username, "email": email, "password": password, "encrypted_password": authentication.encrypt_user_password(password), } raise Unauthorized()
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 post(self, username): # Ensure that we are using database auth. if app.config["AUTHENTICATION_TYPE"] != "Database": raise InvalidRequest("Cannot send a recovery e-mail for non-database auth") if SuperUserPermission().can(): user = pre_oci_model.get_nonrobot_user(username) if user is None: raise NotFound() if superusers.is_superuser(username): raise InvalidRequest("Cannot send a recovery email for a superuser") code = pre_oci_model.create_reset_password_email_code(user.email) send_recovery_email(user.email, code) return {"email": user.email} raise Unauthorized()
def post(self, namespace_name, repository_name, uuid): """ Queues a test notification for this repository. """ test_note = model.queue_test_notification(uuid) if not test_note: raise InvalidRequest( "No repository notification found for: %s, %s, %s" % (namespace_name, repository_name, uuid)) return {}, 200
def _queue_logs_export(start_time, end_time, options, namespace_name, repository_name=None): callback_url = options.get('callback_url') if callback_url: if not callback_url.startswith('https://') and not callback_url.startswith('http://'): raise InvalidRequest('Invalid callback URL') callback_email = options.get('callback_email') if callback_email: if callback_email.find('@') < 0: raise InvalidRequest('Invalid callback e-mail') (start_time, end_time) = _validate_logs_arguments(start_time, end_time) export_id = logs_model.queue_logs_export(start_time, end_time, export_action_logs_queue, namespace_name, repository_name, callback_url, callback_email) if export_id is None: raise InvalidRequest('Invalid export request') return export_id
def delete(self, username): """ Deletes the specified user. """ if SuperUserPermission().can(): user = pre_oci_model.get_nonrobot_user(username) if user is None: raise NotFound() if superusers.is_superuser(username): raise InvalidRequest("Cannot delete a superuser") pre_oci_model.mark_user_for_deletion(username) return "", 204 raise Unauthorized()
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, 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, username): if not authentication.federated_service: abort(404) # Only allowed if there is a logged in user. if not get_authenticated_user(): raise Unauthorized() # Try to link the user with the given *external* username, to an internal record. (user, err_msg) = authentication.link_user(username) if user is None: raise InvalidRequest(err_msg, payload={"username": username}) return { "entity": { "name": user.username, "kind": "user", "is_robot": False, "avatar": avatar.get_data_for_user(user), } }
def post(self, username): if not authentication.federated_service: abort(404) # Only allowed if there is a logged in user. if not get_authenticated_user(): raise Unauthorized() # Try to link the user with the given *external* username, to an internal record. (user, err_msg) = authentication.link_user(username) if user is None: raise InvalidRequest(err_msg, payload={'username': username}) return { 'entity': { 'name': user.username, 'kind': 'user', 'is_robot': False, 'avatar': avatar.get_data_for_user(user) } }
def post(self): if SuperUserPermission().can(): body = request.get_json() key_name = body.get("name", "") if not validate_service_key_name(key_name): raise InvalidRequest("Invalid service key friendly name: %s" % key_name) # Ensure we have a valid expiration date if specified. expiration_date = body.get("expiration", None) if expiration_date is not None: try: expiration_date = datetime.utcfromtimestamp(float(expiration_date)) except ValueError as ve: raise InvalidRequest("Invalid expiration date: %s" % ve) if expiration_date <= datetime.now(): raise InvalidRequest("Expiration date cannot be in the past") # Create the metadata for the key. user = get_authenticated_user() metadata = body.get("metadata", {}) metadata.update( { "created_by": "Quay Superuser Panel", "creator": user.username, "ip": get_request_ip(), } ) # Generate a key with a private key that we *never save*. (private_key, key_id) = pre_oci_model.generate_service_key( body["service"], expiration_date, metadata=metadata, name=key_name ) # Auto-approve the service key. pre_oci_model.approve_service_key( key_id, user, ServiceKeyApprovalType.SUPERUSER, notes=body.get("notes", "") ) # Log the creation and auto-approval of the service key. key_log_metadata = { "kid": key_id, "preshared": True, "service": body["service"], "name": key_name, "expiration_date": expiration_date, "auto_approved": True, } log_action("service_key_create", None, key_log_metadata) log_action("service_key_approve", None, key_log_metadata) return jsonify( { "kid": key_id, "name": key_name, "service": body["service"], "public_key": private_key.publickey().exportKey("PEM").decode("ascii"), "private_key": private_key.exportKey("PEM").decode("ascii"), } ) raise Unauthorized()
def post(self): if SuperUserPermission().can(): body = request.get_json() key_name = body.get('name', '') if not validate_service_key_name(key_name): raise InvalidRequest('Invalid service key friendly name: %s' % key_name) # Ensure we have a valid expiration date if specified. expiration_date = body.get('expiration', None) if expiration_date is not None: try: expiration_date = datetime.utcfromtimestamp( float(expiration_date)) except ValueError as ve: raise InvalidRequest('Invalid expiration date: %s' % ve) if expiration_date <= datetime.now(): raise InvalidRequest( 'Expiration date cannot be in the past') # Create the metadata for the key. user = get_authenticated_user() metadata = body.get('metadata', {}) metadata.update({ 'created_by': 'Quay Superuser Panel', 'creator': user.username, 'ip': get_request_ip(), }) # Generate a key with a private key that we *never save*. (private_key, key_id) = pre_oci_model.generate_service_key(body['service'], expiration_date, metadata=metadata, name=key_name) # Auto-approve the service key. pre_oci_model.approve_service_key(key_id, user, ServiceKeyApprovalType.SUPERUSER, notes=body.get('notes', '')) # Log the creation and auto-approval of the service key. key_log_metadata = { 'kid': key_id, 'preshared': True, 'service': body['service'], 'name': key_name, 'expiration_date': expiration_date, 'auto_approved': True, } log_action('service_key_create', None, key_log_metadata) log_action('service_key_approve', None, key_log_metadata) return jsonify({ 'kid': key_id, 'name': key_name, 'service': body['service'], 'public_key': private_key.publickey().exportKey('PEM'), 'private_key': private_key.exportKey('PEM'), }) raise Unauthorized()