# Licensed to the StackStorm, Inc ('StackStorm') under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
This module contains permission checking decorators for wrapping pecan request handler methods.
"""

from functools import wraps

import pecan

from st2common.rbac import utils

__all__ = [
    'request_user_is_admin',
    'request_user_has_permission',
    'request_user_has_resource_permission'
]


def request_user_is_admin():
    def decorate(func):
        @wraps(func)
        def func_wrapper(*args, **kwargs):
            utils.assert_request_user_is_admin(request=pecan.request)
            return func(*args, **kwargs)
        return func_wrapper
    return decorate


def request_user_has_permission(permission_type):
    def decorate(func):
        @wraps(func)
        def func_wrapper(*args, **kwargs):
            utils.assert_request_user_has_permission(request=pecan.request,
                                                     permission_type=permission_type)
            return func(*args, **kwargs)
        return func_wrapper
    return decorate


def request_user_has_resource_permission(permission_type):
    def decorate(func):
        @wraps(func)
        def func_wrapper(*args, **kwargs):
            # TODO
            resource_db = None
            utils.assert_request_user_has_resource_permission(request=pecan.request,
                                                              resource_db=resource_db,
                                                              permission_type=permission_type)
            return func(*args, **kwargs)
        return func_wrapper
    return decorate

@@ -1814,110 +1814,905 @@
     
-def decorate(func):%0A        @wraps(func)%0A        def func_wrapper(*args, **kwargs):%0A            # TODO
+%22%22%22%0A    A decorator meant to wrap post, put and delete Pecan REST controller methods.%0A%0A    This decorator assumes the first argument passed to the decorated function is a resource%0A    reference or an ID.%0A%0A    Internally, this decorator retrieves the object from the DB so it can perform the permission%0A    checking.%0A%0A    Note: The same query happens inside the decorator function meaning this is not the most%0A    efficient approach and we should eventually cache the %22get one%22 results.%0A    %22%22%22%0A    def decorate(func):%0A        function_name = func.__name__%0A        if function_name not in %5B'post', 'put', 'delete'%5D:%0A            raise Exception('This decorator should only be used to wrap post, put and delete '%0A                            'methods')%0A%0A        @wraps(func)%0A        def func_wrapper(*args, **kwargs):%0A            controller_instance = args%5B0%5D%0A            resource_ref_or_id = args%5B1%5D%0A
 %0A   
@@ -2738,12 +2738,75 @@
 b = 
-None
+controller_instance._get_by_ref_or_id(ref_or_id=resource_ref_or_id)
 %0A   
@@ -3138,28 +3138,30 @@
 wrapper%0A    return decorate%0A
+%0A%0A

Add new decorator for wrappint controller post, put and delete methods.