Team Ai
Apppublic

Underground-Digital/Workflow-Engine

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
members.py152 linesDownload Raw Back to workspace
1from flask_login import current_user2from flask_restful import Resource, abort, marshal_with, reqparse3 4import services5from configs import dify_config6from controllers.console import api7from controllers.console.wraps import (8    account_initialization_required,9    cloud_edition_billing_resource_check,10    setup_required,11)12from extensions.ext_database import db13from fields.member_fields import account_with_role_list_fields14from libs.login import login_required15from models.account import Account, TenantAccountRole16from services.account_service import RegisterService, TenantService17from services.errors.account import AccountAlreadyInTenantError18 19 20class MemberListApi(Resource):21    """List all members of current tenant."""22 23    @setup_required24    @login_required25    @account_initialization_required26    @marshal_with(account_with_role_list_fields)27    def get(self):28        members = TenantService.get_tenant_members(current_user.current_tenant)29        return {"result": "success", "accounts": members}, 20030 31 32class MemberInviteEmailApi(Resource):33    """Invite a new member by email."""34 35    @setup_required36    @login_required37    @account_initialization_required38    @cloud_edition_billing_resource_check("members")39    def post(self):40        parser = reqparse.RequestParser()41        parser.add_argument("emails", type=str, required=True, location="json", action="append")42        parser.add_argument("role", type=str, required=True, default="admin", location="json")43        parser.add_argument("language", type=str, required=False, location="json")44        args = parser.parse_args()45 46        invitee_emails = args["emails"]47        invitee_role = args["role"]48        interface_language = args["language"]49        if not TenantAccountRole.is_non_owner_role(invitee_role):50            return {"code": "invalid-role", "message": "Invalid role"}, 40051 52        inviter = current_user53        invitation_results = []54        console_web_url = dify_config.CONSOLE_WEB_URL55        for invitee_email in invitee_emails:56            try:57                token = RegisterService.invite_new_member(58                    inviter.current_tenant, invitee_email, interface_language, role=invitee_role, inviter=inviter59                )60                invitation_results.append(61                    {62                        "status": "success",63                        "email": invitee_email,64                        "url": f"{console_web_url}/activate?email={invitee_email}&token={token}",65                    }66                )67            except AccountAlreadyInTenantError:68                invitation_results.append(69                    {"status": "success", "email": invitee_email, "url": f"{console_web_url}/signin"}70                )71                break72            except Exception as e:73                invitation_results.append({"status": "failed", "email": invitee_email, "message": str(e)})74 75        return {76            "result": "success",77            "invitation_results": invitation_results,78        }, 20179 80 81class MemberCancelInviteApi(Resource):82    """Cancel an invitation by member id."""83 84    @setup_required85    @login_required86    @account_initialization_required87    def delete(self, member_id):88        member = db.session.query(Account).filter(Account.id == str(member_id)).first()89        if not member:90            abort(404)91 92        try:93            TenantService.remove_member_from_tenant(current_user.current_tenant, member, current_user)94        except services.errors.account.CannotOperateSelfError as e:95            return {"code": "cannot-operate-self", "message": str(e)}, 40096        except services.errors.account.NoPermissionError as e:97            return {"code": "forbidden", "message": str(e)}, 40398        except services.errors.account.MemberNotInTenantError as e:99            return {"code": "member-not-found", "message": str(e)}, 404100        except Exception as e:101            raise ValueError(str(e))102 103        return {"result": "success"}, 204104 105 106class MemberUpdateRoleApi(Resource):107    """Update member role."""108 109    @setup_required110    @login_required111    @account_initialization_required112    def put(self, member_id):113        parser = reqparse.RequestParser()114        parser.add_argument("role", type=str, required=True, location="json")115        args = parser.parse_args()116        new_role = args["role"]117 118        if not TenantAccountRole.is_valid_role(new_role):119            return {"code": "invalid-role", "message": "Invalid role"}, 400120 121        member = db.session.get(Account, str(member_id))122        if not member:123            abort(404)124 125        try:126            TenantService.update_member_role(current_user.current_tenant, member, new_role, current_user)127        except Exception as e:128            raise ValueError(str(e))129 130        # todo: 403131 132        return {"result": "success"}133 134 135class DatasetOperatorMemberListApi(Resource):136    """List all members of current tenant."""137 138    @setup_required139    @login_required140    @account_initialization_required141    @marshal_with(account_with_role_list_fields)142    def get(self):143        members = TenantService.get_dataset_operator_members(current_user.current_tenant)144        return {"result": "success", "accounts": members}, 200145 146 147api.add_resource(MemberListApi, "/workspaces/current/members")148api.add_resource(MemberInviteEmailApi, "/workspaces/current/members/invite-email")149api.add_resource(MemberCancelInviteApi, "/workspaces/current/members/<uuid:member_id>")150api.add_resource(MemberUpdateRoleApi, "/workspaces/current/members/<uuid:member_id>/update-role")151api.add_resource(DatasetOperatorMemberListApi, "/workspaces/current/dataset-operators")152