Skip to content

Commit

Permalink
feat: new editor user permission profile (#4435)
Browse files Browse the repository at this point in the history
Co-authored-by: crazywoola <[email protected]>
Co-authored-by: crazywoola <[email protected]>
  • Loading branch information
3 people authored Jun 14, 2024
1 parent cdb6c80 commit 8bcc5a3
Show file tree
Hide file tree
Showing 49 changed files with 246 additions and 126 deletions.
20 changes: 13 additions & 7 deletions api/controllers/console/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def post(self):
parser.add_argument('icon_background', type=str, location='json')
args = parser.parse_args()

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

if 'mode' not in args or args['mode'] is None:
Expand All @@ -89,8 +89,8 @@ class AppImportApi(Resource):
@cloud_edition_billing_resource_check('apps')
def post(self):
"""Import app"""
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand Down Expand Up @@ -147,7 +147,7 @@ def put(self, app_model):
@get_app_model
def delete(self, app_model):
"""Delete app"""
if not current_user.is_admin_or_owner:
if not current_user.is_editor:
raise Forbidden()

app_service = AppService()
Expand All @@ -164,8 +164,8 @@ class AppCopyApi(Resource):
@marshal_with(app_detail_fields_with_site)
def post(self, app_model):
"""Copy app"""
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand Down Expand Up @@ -238,6 +238,9 @@ class AppSiteStatus(Resource):
@get_app_model
@marshal_with(app_detail_fields)
def post(self, app_model):
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()
parser = reqparse.RequestParser()
parser.add_argument('enable_site', type=bool, required=True, location='json')
args = parser.parse_args()
Expand All @@ -255,6 +258,9 @@ class AppApiStatus(Resource):
@get_app_model
@marshal_with(app_detail_fields)
def post(self, app_model):
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
raise Forbidden()
parser = reqparse.RequestParser()
parser.add_argument('enable_api', type=bool, required=True, location='json')
args = parser.parse_args()
Expand Down
14 changes: 13 additions & 1 deletion api/controllers/console/app/conversation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from flask_restful.inputs import int_range
from sqlalchemy import func, or_
from sqlalchemy.orm import joinedload
from werkzeug.exceptions import NotFound
from werkzeug.exceptions import Forbidden, NotFound

from controllers.console import api
from controllers.console.app.wraps import get_app_model
Expand All @@ -33,6 +33,8 @@ class CompletionConversationApi(Resource):
@get_app_model(mode=AppMode.COMPLETION)
@marshal_with(conversation_pagination_fields)
def get(self, app_model):
if not current_user.is_admin_or_owner:
raise Forbidden()
parser = reqparse.RequestParser()
parser.add_argument('keyword', type=str, location='args')
parser.add_argument('start', type=datetime_string('%Y-%m-%d %H:%M'), location='args')
Expand Down Expand Up @@ -106,6 +108,8 @@ class CompletionConversationDetailApi(Resource):
@get_app_model(mode=AppMode.COMPLETION)
@marshal_with(conversation_message_detail_fields)
def get(self, app_model, conversation_id):
if not current_user.is_admin_or_owner:
raise Forbidden()
conversation_id = str(conversation_id)

return _get_conversation(app_model, conversation_id)
Expand All @@ -115,6 +119,8 @@ def get(self, app_model, conversation_id):
@account_initialization_required
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT])
def delete(self, app_model, conversation_id):
if not current_user.is_admin_or_owner:
raise Forbidden()
conversation_id = str(conversation_id)

conversation = db.session.query(Conversation) \
Expand All @@ -137,6 +143,8 @@ class ChatConversationApi(Resource):
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT])
@marshal_with(conversation_with_summary_pagination_fields)
def get(self, app_model):
if not current_user.is_admin_or_owner:
raise Forbidden()
parser = reqparse.RequestParser()
parser.add_argument('keyword', type=str, location='args')
parser.add_argument('start', type=datetime_string('%Y-%m-%d %H:%M'), location='args')
Expand Down Expand Up @@ -225,6 +233,8 @@ class ChatConversationDetailApi(Resource):
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT])
@marshal_with(conversation_detail_fields)
def get(self, app_model, conversation_id):
if not current_user.is_admin_or_owner:
raise Forbidden()
conversation_id = str(conversation_id)

return _get_conversation(app_model, conversation_id)
Expand All @@ -234,6 +244,8 @@ def get(self, app_model, conversation_id):
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT])
@account_initialization_required
def delete(self, app_model, conversation_id):
if not current_user.is_admin_or_owner:
raise Forbidden()
conversation_id = str(conversation_id)

conversation = db.session.query(Conversation) \
Expand Down
4 changes: 2 additions & 2 deletions api/controllers/console/app/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class AppSite(Resource):
def post(self, app_model):
args = parse_app_site_args()

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be editor, admin, or owner
if not current_user.is_editor:
raise Forbidden()

site = db.session.query(Site). \
Expand Down
12 changes: 6 additions & 6 deletions api/controllers/console/datasets/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ def post(self):
help='Invalid indexing technique.')
args = parser.parse_args()

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

try:
Expand Down Expand Up @@ -195,8 +195,8 @@ def patch(self, dataset_id):
parser.add_argument('retrieval_model', type=dict, location='json', help='Invalid retrieval model.')
args = parser.parse_args()

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

dataset = DatasetService.update_dataset(
Expand All @@ -213,8 +213,8 @@ def patch(self, dataset_id):
def delete(self, dataset_id):
dataset_id_str = str(dataset_id)

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

try:
Expand Down
20 changes: 10 additions & 10 deletions api/controllers/console/datasets/datasets_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ def post(self, dataset_id):
if not dataset:
raise NotFound('Dataset not found.')

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

try:
Expand Down Expand Up @@ -278,8 +278,8 @@ class DatasetInitApi(Resource):
@marshal_with(dataset_and_document_fields)
@cloud_edition_billing_resource_check('vector_space')
def post(self):
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand Down Expand Up @@ -632,8 +632,8 @@ def patch(self, dataset_id, document_id, action):
document_id = str(document_id)
document = self.get_document(dataset_id, document_id)

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

if action == "pause":
Expand Down Expand Up @@ -696,8 +696,8 @@ def put(self, dataset_id, document_id):
doc_type = req_data.get('doc_type')
doc_metadata = req_data.get('doc_metadata')

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

if doc_type is None or doc_metadata is None:
Expand Down Expand Up @@ -743,8 +743,8 @@ def patch(self, dataset_id, document_id, action):

document = self.get_document(dataset_id, document_id)

# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

indexing_cache_key = 'document_{}_indexing'.format(document.id)
Expand Down
8 changes: 4 additions & 4 deletions api/controllers/console/datasets/datasets_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ def patch(self, dataset_id, segment_id, action):
raise NotFound('Dataset not found.')
# check user's model setting
DatasetService.check_dataset_model_setting(dataset)
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

try:
Expand Down Expand Up @@ -302,8 +302,8 @@ def patch(self, dataset_id, document_id, segment_id):
).first()
if not segment:
raise NotFound('Segment not found.')
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()
try:
DatasetService.check_dataset_permission(dataset, current_user)
Expand Down
20 changes: 10 additions & 10 deletions api/controllers/console/tag/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def get(self):
@login_required
@account_initialization_required
def post(self):
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand Down Expand Up @@ -67,8 +67,8 @@ class TagUpdateDeleteApi(Resource):
@account_initialization_required
def patch(self, tag_id):
tag_id = str(tag_id)
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand All @@ -94,8 +94,8 @@ def patch(self, tag_id):
@account_initialization_required
def delete(self, tag_id):
tag_id = str(tag_id)
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

TagService.delete_tag(tag_id)
Expand All @@ -109,8 +109,8 @@ class TagBindingCreateApi(Resource):
@login_required
@account_initialization_required
def post(self):
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand All @@ -134,8 +134,8 @@ class TagBindingDeleteApi(Resource):
@login_required
@account_initialization_required
def post(self):
# The role of the current user in the ta table must be admin or owner
if not current_user.is_admin_or_owner:
# The role of the current user in the ta table must be admin, owner, or editor
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
Expand Down
4 changes: 2 additions & 2 deletions api/controllers/console/workspace/members.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def post(self):
invitee_emails = args['emails']
invitee_role = args['role']
interface_language = args['language']
if invitee_role not in [TenantAccountRole.ADMIN, TenantAccountRole.NORMAL]:
if not TenantAccountRole.is_non_owner_role(invitee_role):
return {'code': 'invalid-role', 'message': 'Invalid role'}, 400

inviter = current_user
Expand Down Expand Up @@ -114,7 +114,7 @@ def put(self, member_id):
args = parser.parse_args()
new_role = args['role']

if new_role not in ['admin', 'normal', 'owner']:
if not TenantAccountRole.is_valid_role(new_role):
return {'code': 'invalid-role', 'message': 'Invalid role'}, 400

member = Account.query.get(str(member_id))
Expand Down
8 changes: 5 additions & 3 deletions api/controllers/console/workspace/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from core.model_runtime.errors.validate import CredentialsValidateFailedError
from core.model_runtime.utils.encoders import jsonable_encoder
from libs.login import login_required
from models.account import TenantAccountRole
from services.model_load_balancing_service import ModelLoadBalancingService
from services.model_provider_service import ModelProviderService

Expand Down Expand Up @@ -43,6 +42,9 @@ def get(self):
@login_required
@account_initialization_required
def post(self):
if not current_user.is_admin_or_owner:
raise Forbidden()

parser = reqparse.RequestParser()
parser.add_argument('model_settings', type=list, required=True, nullable=False, location='json')
args = parser.parse_args()
Expand Down Expand Up @@ -96,7 +98,7 @@ def get(self, provider):
@login_required
@account_initialization_required
def post(self, provider: str):
if not TenantAccountRole.is_privileged_role(current_user.current_tenant.current_role):
if not current_user.is_admin_or_owner:
raise Forbidden()

tenant_id = current_user.current_tenant_id
Expand Down Expand Up @@ -162,7 +164,7 @@ def post(self, provider: str):
@login_required
@account_initialization_required
def delete(self, provider: str):
if not TenantAccountRole.is_privileged_role(current_user.current_tenant.current_role):
if not current_user.is_admin_or_owner:
raise Forbidden()

tenant_id = current_user.current_tenant_id
Expand Down
18 changes: 17 additions & 1 deletion api/models/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ def get_integrates(self) -> list[db.Model]:
def is_admin_or_owner(self):
return TenantAccountRole.is_privileged_role(self._current_tenant.current_role)

@property
def is_editor(self):
return TenantAccountRole.is_editing_role(self._current_tenant.current_role)

class TenantStatus(str, enum.Enum):
NORMAL = 'normal'
Expand All @@ -115,11 +118,24 @@ class TenantStatus(str, enum.Enum):
class TenantAccountRole(str, enum.Enum):
OWNER = 'owner'
ADMIN = 'admin'
EDITOR = 'editor'
NORMAL = 'normal'

@staticmethod
def is_valid_role(role: str) -> bool:
return role and role in {TenantAccountRole.OWNER, TenantAccountRole.ADMIN, TenantAccountRole.EDITOR, TenantAccountRole.NORMAL}

@staticmethod
def is_privileged_role(role: str) -> bool:
return role and role in {TenantAccountRole.ADMIN, TenantAccountRole.OWNER}
return role and role in {TenantAccountRole.OWNER, TenantAccountRole.ADMIN}

@staticmethod
def is_non_owner_role(role: str) -> bool:
return role and role in {TenantAccountRole.ADMIN, TenantAccountRole.EDITOR, TenantAccountRole.NORMAL}

@staticmethod
def is_editing_role(role: str) -> bool:
return role and role in {TenantAccountRole.OWNER, TenantAccountRole.ADMIN, TenantAccountRole.EDITOR}


class Tenant(db.Model):
Expand Down
Loading

0 comments on commit 8bcc5a3

Please sign in to comment.