add member check

pull/22346/head
Yansong Zhang 10 months ago
parent 1c23899461
commit 26badcc15f

@ -483,6 +483,7 @@ ENDPOINT_URL_TEMPLATE=http://localhost:5002/e/{hook_id}
# Reset password token expiry minutes
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES=5
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES=5
CREATE_TIDB_SERVICE_JOB_ENABLED=false

@ -36,6 +36,11 @@ class SecurityConfig(BaseSettings):
default=5,
)
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES: PositiveInt = Field(
description="Duration in minutes for which a owner transfer token remains valid",
default=5,
)
LOGIN_DISABLED: bool = Field(
description="Whether to disable login checks",
default=False,

@ -95,3 +95,14 @@ class OwnerTransferLimitError(BaseHTTPException):
error_code = "owner_transfer_limit"
description = "Too many failed owner transfer attempts. Please try again in 24 hours."
code = 429
class NotOwnerError(BaseHTTPException):
error_code = "not_owner"
description = "You are not the owner of the workspace."
code = 400
class CannotTransferOwnerToSelfError(BaseHTTPException):
error_code = "cannot_transfer_owner_to_self"
description = "You cannot transfer ownership to yourself."
code = 400

@ -7,7 +7,7 @@ from flask_restful import Resource, abort, marshal_with, reqparse
import services
from configs import dify_config
from controllers.console import api
from controllers.console.auth.error import EmailCodeError, InvalidEmailError, InvalidTokenError, OwnerTransferLimitError
from controllers.console.auth.error import EmailCodeError, InvalidEmailError, InvalidTokenError, OwnerTransferLimitError,NotOwnerError,CannotTransferOwnerToSelfError
from controllers.console.error import EmailSendIpLimitError, WorkspaceMembersLimitExceeded
from controllers.console.wraps import (
account_initialization_required,
@ -172,10 +172,17 @@ class SendOwnerTransferEmailApi(Resource):
parser.add_argument("language", type=str, required=False, location="json")
args = parser.parse_args()
# check if the current user is the owner of the workspace
if not TenantService.is_owner(current_user, current_user.current_tenant):
raise NotOwnerError()
if current_user.id == str(member_id):
raise CannotTransferOwnerToSelfError()
ip_address = extract_remote_ip(request)
if AccountService.is_email_send_ip_limit(ip_address):
raise EmailSendIpLimitError()
if args["language"] is not None and args["language"] == "zh-Hans":
language = "zh-Hans"
else:
@ -199,7 +206,7 @@ class SendOwnerTransferEmailApi(Resource):
return {"result": "success", "data": token}
class OwnerTransferCheckEApi(Resource):
class OwnerTransferCheckApi(Resource):
@setup_required
@login_required
@account_initialization_required
@ -209,10 +216,13 @@ class OwnerTransferCheckEApi(Resource):
parser.add_argument("code", type=str, required=True, location="json")
parser.add_argument("token", type=str, required=True, nullable=False, location="json")
args = parser.parse_args()
# check if the current user is the owner of the workspace
if not TenantService.is_owner(current_user, current_user.current_tenant):
raise NotOwnerError()
user_email = current_user.email
is_owner_transfer_error_rate_limit = AccountService.is_owner_transfer_error_rate_limit(args["email"])
is_owner_transfer_error_rate_limit = AccountService.is_owner_transfer_error_rate_limit(user_email)
if is_owner_transfer_error_rate_limit:
raise OwnerTransferLimitError()
@ -224,7 +234,7 @@ class OwnerTransferCheckEApi(Resource):
raise InvalidEmailError()
if args["code"] != token_data.get("code"):
AccountService.add_owner_transfer_error_rate_limit(args["email"])
AccountService.add_owner_transfer_error_rate_limit(user_email)
raise EmailCodeError()
# Verified, revoke the first token
@ -233,7 +243,7 @@ class OwnerTransferCheckEApi(Resource):
# Refresh token data by generating a new token
_, new_token = AccountService.generate_owner_transfer_token(user_email, code=args["code"], additional_data={})
AccountService.reset_owner_transfer_error_rate_limit(args["email"])
AccountService.reset_owner_transfer_error_rate_limit(user_email)
return {"is_valid": True, "email": token_data.get("email"), "token": new_token}
@ -246,15 +256,21 @@ class OwnerTransfer(Resource):
parser = reqparse.RequestParser()
parser.add_argument("token", type=str, required=True, nullable=False, location="json")
args = parser.parse_args()
# check if the current user is the owner of the workspace
if not TenantService.is_owner(current_user, current_user.current_tenant):
raise NotOwnerError()
if current_user.id == str(member_id):
raise CannotTransferOwnerToSelfError()
transfer_token_data = AccountService.get_owner_transfer_data(args["token"])
if not transfer_token_data:
raise InvalidTokenError()
if transfer_token_data.get("phase", "") != "owner_transfer":
print(transfer_token_data, "transfer_token_data")
raise InvalidTokenError()
if transfer_token_data.get("email") != current_user.email:
print(transfer_token_data.get("email"), current_user.email)
raise InvalidEmailError()
AccountService.revoke_owner_transfer_token(args["token"])
@ -295,5 +311,5 @@ api.add_resource(DatasetOperatorMemberListApi, "/workspaces/current/dataset-oper
api.add_resource(
SendOwnerTransferEmailApi, "/workspaces/current/members/<uuid:member_id>/send-owner-transfer-confirm-email"
)
api.add_resource(OwnerTransferCheckEApi, "/workspaces/current/members/owner-transfer-check")
api.add_resource(OwnerTransferCheckApi, "/workspaces/current/members/owner-transfer-check")
api.add_resource(OwnerTransfer, "/workspaces/current/members/<uuid:member_id>/owner-transfer")

@ -1083,6 +1083,10 @@ class TenantService:
return cast(dict, tenant.custom_config_dict)
@staticmethod
def is_owner(account: Account, tenant: Tenant) -> bool:
return TenantService.get_user_role(account, tenant) == TenantAccountRole.OWNER
class RegisterService:
@classmethod

@ -15,7 +15,6 @@ def send_owner_transfer_confirm_task(language: str, to: str, code: str, workspac
Async Send owner transfer confirm mail
:param language: Language in which the email should be sent (e.g., 'en', 'zh')
:param to: Recipient email address
:param code: Change email code
:param workspace: Workspace name
:param member: Member name
"""
@ -59,12 +58,11 @@ def send_owner_transfer_confirm_task(language: str, to: str, code: str, workspac
@shared_task(queue="mail")
def send_old_owner_transfer_notify_email_task(language: str, to: str, code: str, workspace: str, new_owner_email: str):
def send_old_owner_transfer_notify_email_task(language: str, to: str, workspace: str, new_owner_email: str):
"""
Async Send owner transfer confirm mail
:param language: Language in which the email should be sent (e.g., 'en', 'zh')
:param to: Recipient email address
:param code: Change email code
:param workspace: Workspace name
:param new_owner_email: New owner email
"""
@ -116,7 +114,7 @@ def send_old_owner_transfer_notify_email_task(language: str, to: str, code: str,
@shared_task(queue="mail")
def send_new_owner_transfer_notify_email_task(language: str, to: str, code: str, workspace: str):
def send_new_owner_transfer_notify_email_task(language: str, to: str, workspace: str):
"""
Async Send owner transfer confirm mail
:param language: Language in which the email should be sent (e.g., 'en', 'zh')

@ -204,6 +204,7 @@ ENDPOINT_URL_TEMPLATE=http://localhost:5002/e/{hook_id}
# Reset password token expiry minutes
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES=5
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES=5
CREATE_TIDB_SERVICE_JOB_ENABLED=false

@ -769,6 +769,7 @@ INVITE_EXPIRY_HOURS=72
# Reset password token valid time (minutes),
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES=5
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES=5
# The sandbox service endpoint.
CODE_EXECUTION_ENDPOINT=http://sandbox:8194

@ -334,6 +334,7 @@ x-shared-env: &shared-api-worker-env
INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72}
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES: ${RESET_PASSWORD_TOKEN_EXPIRY_MINUTES:-5}
CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES: ${CHANGE_EMAIL_TOKEN_EXPIRY_MINUTES:-5}
OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES: ${OWNER_TRANSFER_TOKEN_EXPIRY_MINUTES:-5}
CODE_EXECUTION_ENDPOINT: ${CODE_EXECUTION_ENDPOINT:-http://sandbox:8194}
CODE_EXECUTION_API_KEY: ${CODE_EXECUTION_API_KEY:-dify-sandbox}
CODE_MAX_NUMBER: ${CODE_MAX_NUMBER:-9223372036854775807}

Loading…
Cancel
Save