瀏覽代碼

walle 2.0 alpha - permission 若喜欢请不吝为我们项目点个star

walle 6 年之前
父節點
當前提交
3918fa402e

+ 1 - 1
tests/utils.py

@@ -7,7 +7,7 @@
     :author: wushuiyong@walle-web.io
 """
 import json
-
+from flask import current_app
 
 def response_success(response):
     assert 200 <= response.status_code < 300, 'Received %d response: %s' % (response.status_code, response.data)

+ 3 - 33
walle/api/deploy.py

@@ -15,43 +15,13 @@ from walle.service.deployer import Deployer
 
 
 class DeployAPI(SecurityResource):
+
     def get(self, task_id=None):
         """
-        fetch environment list or one item
-        /environment/<int:env_id>
+        fetch deploy list or one item
+        /deploy/<int:env_id>
 
         :return:
         """
         super(DeployAPI, self).get()
 
-    # def get(self, method):
-    #     """
-    #     fetch role list or one role
-    #
-    #     :return:
-    #     """
-    #     if method == 'menu':
-    #         return self.menu()
-    #     elif method == 'mail':
-    #         return self.mail()
-    #     elif method == 'walle':
-    #         return self.walless()
-
-    def post(self):
-        """
-        fetch role list or one role
-
-        :return:
-        """
-        super(DeployAPI, self).post()
-
-        task_id = request.form['task_id']
-        if not task_id or not task_id.isdigit():
-            return self.render_json(code=-1)
-        wi = Deployer(task_id)
-        ret = wi.walle_deploy()
-        record = RecordModel().fetch(task_id)
-        return self.render_json(data={
-            'command': '',
-            'record': record,
-        })

+ 8 - 4
walle/api/environment.py

@@ -9,16 +9,16 @@
 """
 
 from flask import request
+from walle.api.api import SecurityResource
 from walle.form.environment import EnvironmentForm
 from walle.model.environment import EnvironmentModel
-from walle.api.api import SecurityResource
 from walle.service.extensions import permission
 from walle.service.rbac.role import *
 
-class EnvironmentAPI(SecurityResource):
 
-    controller = 'environment'
+class EnvironmentAPI(SecurityResource):
 
+    @permission.upper_master
     def get(self, env_id=None):
         """
         fetch environment list or one item
@@ -53,7 +53,8 @@ class EnvironmentAPI(SecurityResource):
         env_model = EnvironmentModel()
 
         env_list, count = env_model.list(page=page, size=size, kw=kw, space_id=self.space_id)
-        return self.list_json(list=env_list, count=count, table=table, enable_create=permission.role_upper_master() and current_user.role != SUPER)
+        return self.list_json(list=env_list, count=count, table=table,
+                              enable_create=permission.role_upper_master() and current_user.role != SUPER)
 
     def item(self, env_id):
         """
@@ -69,6 +70,7 @@ class EnvironmentAPI(SecurityResource):
             return self.render_json(code=-1)
         return self.render_json(data=env_info)
 
+    @permission.upper_master
     def post(self):
         """
         create a environment
@@ -89,6 +91,7 @@ class EnvironmentAPI(SecurityResource):
         else:
             return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_master
     def put(self, env_id):
         """
         update environment
@@ -107,6 +110,7 @@ class EnvironmentAPI(SecurityResource):
         else:
             return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_master
     def delete(self, env_id):
         """
         remove an environment

+ 2 - 1
walle/api/general.py

@@ -25,7 +25,8 @@ from walle.service.extensions import permission
 class GeneralAPI(SecurityResource):
     actions = ['menu', 'websocket']
 
-    @permission.gte_develop_or_uid
+    # TODO 更细致的检查
+    @permission.upper_reporter
     def get(self, action):
         """
         fetch role list or one role

+ 5 - 1
walle/api/project.py

@@ -20,7 +20,8 @@ from walle.service.rbac.role import *
 
 
 class ProjectAPI(SecurityResource):
-    @permission.gte_develop_or_uid
+
+    @permission.upper_reporter
     def get(self, action=None, project_id=None):
         """
         fetch project list or one item
@@ -67,6 +68,7 @@ class ProjectAPI(SecurityResource):
 
         return self.render_json(data=project_info)
 
+    @permission.upper_developer
     def post(self):
         """
         create a project
@@ -90,6 +92,7 @@ class ProjectAPI(SecurityResource):
         else:
             return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_developer
     def put(self, project_id, action=None):
         """
         update project
@@ -113,6 +116,7 @@ class ProjectAPI(SecurityResource):
         else:
             return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_developer
     def delete(self, project_id):
         """
         remove an project

+ 2 - 0
walle/api/repo.py

@@ -10,11 +10,13 @@
 from flask import request, abort
 from walle.api.api import SecurityResource
 from walle.service.deployer import Deployer
+from walle.service.extensions import permission
 
 
 class RepoAPI(SecurityResource):
     actions = ['tags', 'branches', 'commits']
 
+    @permission.upper_reporter
     def get(self, action, commit=None):
         """
         fetch project list or one item

+ 5 - 1
walle/api/server.py

@@ -17,6 +17,8 @@ from walle.service.rbac.role import *
 
 
 class ServerAPI(SecurityResource):
+
+    @permission.upper_developer
     def get(self, id=None):
         """
         fetch environment list or one item
@@ -28,6 +30,7 @@ class ServerAPI(SecurityResource):
 
         return self.item(id) if id else self.list()
 
+    @permission.upper_developer
     def list(self):
         """
         fetch environment list
@@ -77,6 +80,7 @@ class ServerAPI(SecurityResource):
         else:
             return self.render_json(Code.form_error, message=form.errors)
 
+    @permission.upper_developer
     def put(self, id):
         """
         update environment
@@ -86,7 +90,6 @@ class ServerAPI(SecurityResource):
         """
         super(ServerAPI, self).put()
 
-
         form = ServerForm(request.form, csrf_enabled=False)
         form.set_id(id)
         if form.validate_on_submit():
@@ -96,6 +99,7 @@ class ServerAPI(SecurityResource):
         else:
             return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_developer
     def delete(self, id):
         """
         remove an environment

+ 15 - 0
walle/api/space.py

@@ -24,6 +24,7 @@ from walle.service.rbac.role import *
 class SpaceAPI(SecurityResource):
     actions = ['members', 'item', 'list', 'member', 'switch']
 
+    @permission.upper_developer
     def get(self, space_id=None, action=None):
         """
         fetch space list or one item
@@ -70,6 +71,7 @@ class SpaceAPI(SecurityResource):
             return self.render_json(code=-1)
         return self.render_json(data=space_info)
 
+    @permission.upper_master
     def post(self):
         """
         create a space
@@ -115,6 +117,7 @@ class SpaceAPI(SecurityResource):
         else:
             abort(404)
 
+    @permission.upper_master
     def update(self, space_id):
         form = SpaceForm(request.form, csrf_enabled=False)
         form.set_id(space_id)
@@ -132,6 +135,7 @@ class SpaceAPI(SecurityResource):
         else:
             return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_master
     def delete(self, space_id):
         """
         remove an environment
@@ -156,6 +160,11 @@ class SpaceAPI(SecurityResource):
         return self.render_json()
 
     def member(self, space_id):
+        '''
+        查看成员
+        @param space_id:
+        @return:
+        '''
         space_id = session['space_id']
         user_id = request.form['user_id']
         role = request.form['role']
@@ -163,7 +172,13 @@ class SpaceAPI(SecurityResource):
         members = MemberModel(group_id=space_id).member(user_id=user_id, role=role, group_id=space_id)
         return self.render_json(data=members)
 
+    @permission.upper_developer
     def members(self, space_id):
+        '''
+        更新组成员
+        @param space_id:
+        @return:
+        '''
         page = int(request.args.get('page', 1))
         page = page - 1 if page else 0
         size = int(request.args.get('size', 10))

+ 1 - 1
walle/api/task.py

@@ -41,7 +41,7 @@ class TaskAPI(SecurityResource):
 
         task_model = TaskModel()
         task_list, count = task_model.list(page=page, size=size, kw=kw, space_id=self.space_id)
-        return self.list_json(list=task_list, count=count, enable_create=permission.role_upper_report() and current_user.role != SUPER)
+        return self.list_json(list=task_list, count=count, enable_create=permission.role_upper_reporter() and current_user.role != SUPER)
 
     def item(self, task_id):
         """

+ 8 - 1
walle/api/user.py

@@ -22,6 +22,7 @@ from werkzeug.security import generate_password_hash
 class UserAPI(SecurityResource):
     actions = ['avatar', 'block', 'active']
 
+    @permission.upper_developer
     def get(self, user_id=None, method=None):
         """
         fetch user list or one user
@@ -84,6 +85,10 @@ class UserAPI(SecurityResource):
         if action and action == 'avatar':
             return self.avatar(user_id)
 
+        return self.create_user()
+
+    @permission.upper_developer
+    def create_user(self):
         form = RegistrationForm(request.form, csrf_enabled=False)
         if form.validate_on_submit():
             user_info = form.form2dict()
@@ -91,7 +96,7 @@ class UserAPI(SecurityResource):
             user = UserModel().add(user_info)
             # send an email
             message = u"""Hi, %s
-                    <br> <br>Welcome to walle, it cost a lot of time and lock to meet you, enjoy it.
+                    <br> <br>Welcome to walle, it cost a lot of time and lock to meet you, enjoy it : )
                     <br><br>name: %s<br>password: %s""" \
                               % (user.username, user.email, form.password.data)
             emails.send_email(user.email, 'Welcome to walle', message, '')
@@ -99,6 +104,7 @@ class UserAPI(SecurityResource):
             return self.render_json(data=user.item(user_id=user.id))
         return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_developer
     def put(self, user_id, action=None):
         """
         edit user
@@ -123,6 +129,7 @@ class UserAPI(SecurityResource):
 
         return self.render_error(code=Code.form_error, message=form.errors)
 
+    @permission.upper_developer
     def delete(self, user_id):
         """
         remove a user with his group relation

+ 1 - 1
walle/model/project.py

@@ -188,7 +188,7 @@ class ProjectModel(SurrogatePK, Model):
 
     def enable(self):
         return {
-            'enable_update': permission.is_gte_develop_or_uid(self.user_id),
+            'enable_update': permission.role_upper_developer(),
             'enable_delete': permission.enable_uid(self.user_id) or permission.role_upper_developer(),
             'enable_create': False,
             'enable_online': False,

+ 1 - 1
walle/service/code.py

@@ -39,7 +39,7 @@ class Code():
     code_msg = {
         unlogin: '未登录',
         error_pwd: '账号密码错误',
-        not_allow: '无此权限',
+        not_allow: '无此资源权限',
         params_error: '参数错误',
         space_empty: '尚未开通空间,请联系空间负责人加入空间',
         space_error: '无此空间权限',

+ 54 - 9
walle/service/rbac/role.py

@@ -12,6 +12,7 @@ from flask import session
 from flask_login import login_required, current_user
 from walle.service.code import Code
 from walle.service.error import WalleError
+from flask import current_app
 
 GUEST = 'GUEST'
 REPORT = 'REPORT'
@@ -49,25 +50,69 @@ class Permission():
     def init_app(self, app):
         self.app = app
 
-    def gte_develop_or_uid(self, func):
+    def upper_owner(self, func):
+        '''
+        角色高于owner
+        @param func:
+        @return:
+        '''
         @wraps(func)
         @login_required
         def decorator(*args, **kwargs):
-            if self.is_gte_develop_or_uid(current_user.id):
+            if self.role_upper_owner():
                 return func(*args, **kwargs)
 
             raise WalleError(Code.not_allow)
 
         return decorator
 
-    def is_gte_develop_or_uid(self, uid=None):
-        if uid is None:
-            uid = current_user.id
+    def upper_master(self, func):
+        '''
+        角色高于master
+        @param func:
+        @return:
+        '''
+        @wraps(func)
+        @login_required
+        def decorator(*args, **kwargs):
+            if self.role_upper_master():
+                return func(*args, **kwargs)
 
-        if self.enable_uid(uid) or self.role_upper_developer():
-            return True
+            raise WalleError(Code.not_allow)
 
-        return False
+        return decorator
+
+    def upper_developer(self, func):
+        '''
+        角色高于developer
+        @param func:
+        @return:
+        '''
+        @wraps(func)
+        @login_required
+        def decorator(*args, **kwargs):
+            if self.role_upper_developer():
+                return func(*args, **kwargs)
+
+            raise WalleError(Code.not_allow)
+
+        return decorator
+
+    def upper_reporter(self, func):
+        '''
+        角色高于reporter
+        @param func:
+        @return:
+        '''
+        @wraps(func)
+        @login_required
+        def decorator(*args, **kwargs):
+            if self.role_upper_reporter():
+                return func(*args, **kwargs)
+
+            raise WalleError(Code.not_allow)
+
+        return decorator
 
     @staticmethod
     def list_enable(self, list, access_level):
@@ -131,7 +176,7 @@ class Permission():
         '''
         return self.role_upper(DEVELOPER, role)
 
-    def role_upper_report(self, role=None):
+    def role_upper_reporter(self, role=None):
         '''
         项目project的角色role比developer级别更高, 传参, 不传则
         空间space的角色role比developer级别更高, 不用传, 默认从session中取