Exemplo n.º 1
0
def check_access(node, auth, action, cas_resp):
    """Verify that user can perform requested action on resource. Raise appropriate
    error code if action cannot proceed.
    """
    permission = permission_map.get(action, None)
    if permission is None:
        raise HTTPError(httplib.BAD_REQUEST)

    if cas_resp:
        if permission == 'read':
            if node.is_public:
                return True
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_READ
        else:
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_WRITE
        if not cas_resp.authenticated \
           or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']):
            raise HTTPError(httplib.FORBIDDEN)

    if permission == 'read' and node.can_view(auth):
        return True
    if permission == 'write' and node.can_edit(auth):
        return True

    # Users attempting to register projects with components might not have
    # `write` permissions for all components. This will result in a 403 for
    # all `copyto` actions as well as `copyfrom` actions if the component
    # in question is not public. To get around this, we have to recursively
    # check the node's parent node to determine if they have `write`
    # permissions up the stack.
    # TODO(hrybacki): is there a way to tell if this is for a registration?
    # All nodes being registered that receive the `copyto` action will have
    # `node.is_registration` == True. However, we have no way of telling if
    # `copyfrom` actions are originating from a node being registered.
    # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
    if action == 'copyfrom' or (action == 'copyto' and node.is_registration):
        parent = node.parent_node
        while parent:
            if parent.can_edit(auth):
                return True
            parent = parent.parent_node

    # Users with the PREREG_ADMIN_TAG should be allowed to download files
    # from prereg challenge draft registrations.
    try:
        prereg_schema = MetaSchema.find_one(
            Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2))
        allowed_nodes = [node] + node.parents
        prereg_draft_registration = DraftRegistration.find(
            Q('branched_from', 'in', [n._id for n in allowed_nodes])
            & Q('registration_schema', 'eq', prereg_schema))
        if action == 'download' and \
                    auth.user is not None and \
                    prereg_draft_registration.count() > 0 and \
                    settings.PREREG_ADMIN_TAG in auth.user.system_tags:
            return True
    except NoResultsFound:
        pass

    raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)
Exemplo n.º 2
0
 def get_serializer_class(self):
     if self.request.auth:
         scopes = self.request.auth.attributes['accessTokenScope']
         if (CoreScopes.USER_EMAIL_READ in normalize_scopes(scopes)
                 and self.request.user == self.get_user()):
             return ReadEmailUserDetailSerializer
     return UserDetailSerializer
Exemplo n.º 3
0
def check_access(node, auth, action, cas_resp):
    """Verify that user can perform requested action on resource. Raise appropriate
    error code if action cannot proceed.
    """
    permission = permission_map.get(action, None)
    if permission is None:
        raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

    # Permissions for DraftNode should be based upon the draft registration
    if isinstance(node, DraftNode):
        node = node.registered_draft.first()

    if cas_resp:
        if permission == permissions.READ:
            if node.can_view_files(auth=None):
                return True
            required_scope = node.file_read_scope
        else:
            required_scope = node.file_write_scope

        if not cas_resp.authenticated \
           or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']):
            raise HTTPError(http_status.HTTP_403_FORBIDDEN)

    if permission == permissions.READ:
        if node.can_view_files(auth):
            return True
        # The user may have admin privileges on a parent node, in which
        # case they should have read permissions
        if getattr(node, 'is_registration', False) and node.registered_from.can_view(auth):
            return True
    if permission == permissions.WRITE and node.can_edit(auth):
        return True

    # Users attempting to register projects with components might not have
    # `write` permissions for all components. This will result in a 403 for
    # all `upload` actions as well as `copyfrom` actions if the component
    # in question is not public. To get around this, we have to recursively
    # check the node's parent node to determine if they have `write`
    # permissions up the stack.
    # TODO(hrybacki): is there a way to tell if this is for a registration?
    # All nodes being registered that receive the `upload` action will have
    # `node.is_registration` == True. However, we have no way of telling if
    # `copyfrom` actions are originating from a node being registered.
    # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
    if isinstance(node, AbstractNode):
        if action == 'copyfrom' or (action == 'upload' and node.is_registration):
            parent = node.parent_node
            while parent:
                if parent.can_edit(auth):
                    return True
                parent = parent.parent_node

    raise HTTPError(http_status.HTTP_403_FORBIDDEN if auth.user else http_status.HTTP_401_UNAUTHORIZED)
Exemplo n.º 4
0
def has_admin_scope(request):
    """ Helper function to determine if a request should be treated
        as though it has the `osf.admin` scope. This includes both
        tokened requests that do, and requests that are made via the
        OSF (i.e. have an osf cookie)
    """
    cookie = request.COOKIES.get(website_settings.COOKIE_NAME)
    if cookie:
        return bool(get_session_from_cookie(cookie))

    token = request.auth
    if token is None or not isinstance(token, CasResponse):
        return False

    return set(ComposedScopes.ADMIN_LEVEL).issubset(normalize_scopes(token.attributes['accessTokenScope']))
Exemplo n.º 5
0
def has_admin_scope(request):
    """ Helper function to determine if a request should be treated
        as though it has the `osf.admin` scope. This includes both
        tokened requests that do, and requests that are made via the
        OSF (i.e. have an osf cookie)
    """
    cookie = request.COOKIES.get(website_settings.COOKIE_NAME)
    if cookie:
        return bool(get_session_from_cookie(cookie))

    token = request.auth
    if token is None or not isinstance(token, CasResponse):
        return False

    return set(ComposedScopes.ADMIN_LEVEL).issubset(normalize_scopes(token.attributes['accessTokenScope']))
Exemplo n.º 6
0
    def _verify_scopes(self, request, view, token):
        # Anything calling this method should handle the case where
        # `token is None` before making this call.

        required_scopes = self._get_scopes(request, view)

        # Scopes are returned as a space-delimited list in the token
        allowed_scopes = token.attributes['accessTokenScope']
        try:
            normalized_scopes = oauth_scopes.normalize_scopes(allowed_scopes)
        except KeyError:
            # This should never fire: it implies that CAS issued a scope name not in the master list of scopes
            raise exceptions.APIException('OAuth2 token specifies unrecognized scope. User token specifies '
                                          'the following scopes: {}'.format(', '.join(allowed_scopes)))

        return required_scopes.issubset(normalized_scopes)
Exemplo n.º 7
0
    def _verify_scopes(self, request, view, token):
        # Anything calling this method should handle the case where
        # `token is None` before making this call.

        required_scopes = self._get_scopes(request, view)

        # Scopes are returned as a space-delimited list in the token
        allowed_scopes = token.attributes['accessTokenScope']
        try:
            normalized_scopes = oauth_scopes.normalize_scopes(allowed_scopes)
        except KeyError:
            # This should never fire: it implies that CAS issued a scope name not in the master list of scopes
            raise exceptions.APIException(
                'OAuth2 token specifies unrecognized scope. User token specifies '
                'the following scopes: {}'.format(', '.join(allowed_scopes)))

        return required_scopes.issubset(normalized_scopes)
Exemplo n.º 8
0
def check_access(node, auth, action, cas_resp):
    """Verify that user can perform requested action on resource. Raise appropriate
    error code if action cannot proceed.
    """
    permission = permission_map.get(action, None)
    if permission is None:
        raise HTTPError(httplib.BAD_REQUEST)

    if cas_resp:
        if permission == 'read':
            if node.is_public:
                return True
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_READ
        else:
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_WRITE
        if not cas_resp.authenticated \
           or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']):
            raise HTTPError(httplib.FORBIDDEN)

    if permission == 'read' and node.can_view(auth):
        return True
    if permission == 'write' and node.can_edit(auth):
        return True

    # Users attempting to register projects with components might not have
    # `write` permissions for all components. This will result in a 403 for
    # all `copyto` actions as well as `copyfrom` actions if the component
    # in question is not public. To get around this, we have to recursively
    # check the node's parent node to determine if they have `write`
    # permissions up the stack.
    # TODO(hrybacki): is there a way to tell if this is for a registration?
    # All nodes being registered that receive the `copyto` action will have
    # `node.is_registration` == True. However, we have no way of telling if
    # `copyfrom` actions are originating from a node being registered.
    # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
    if action == 'copyfrom' or (action == 'copyto' and node.is_registration):
        parent = node.parent_node
        while parent:
            if parent.can_edit(auth):
                return True
            parent = parent.parent_node

    raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)
Exemplo n.º 9
0
def check_access(node, auth, action, cas_resp):
    """Verify that user can perform requested action on resource. Raise appropriate
    error code if action cannot proceed.
    """
    permission = permission_map.get(action, None)
    if permission is None:
        raise HTTPError(httplib.BAD_REQUEST)

    if cas_resp:
        if permission == 'read':
            if node.is_public:
                return True
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_READ
        else:
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_WRITE
        if not cas_resp.authenticated \
           or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']):
            raise HTTPError(httplib.FORBIDDEN)

    if permission == 'read' and node.can_view(auth):
        return True
    if permission == 'write' and node.can_edit(auth):
        return True

    # Users attempting to register projects with components might not have
    # `write` permissions for all components. This will result in a 403 for
    # all `copyto` actions as well as `copyfrom` actions if the component
    # in question is not public. To get around this, we have to recursively
    # check the node's parent node to determine if they have `write`
    # permissions up the stack.
    # TODO(hrybacki): is there a way to tell if this is for a registration?
    # All nodes being registered that receive the `copyto` action will have
    # `node.is_registration` == True. However, we have no way of telling if
    # `copyfrom` actions are originating from a node being registered.
    # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
    if action == 'copyfrom' or (action == 'copyto' and node.is_registration):
        parent = node.parent_node
        while parent:
            if parent.can_edit(auth):
                return True
            parent = parent.parent_node

    raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)
Exemplo n.º 10
0
    def has_permission(self, request, view):
        token = request.auth

        if token is None or not isinstance(token, CasResponse):
            # Assumption: user authenticated via non-oauth means, so don't check token permissions.
            return True

        required_scopes = self._get_scopes(request, view)

        # Scopes are returned as a space-delimited list in the token
        allowed_scopes = token.attributes['accessTokenScope']

        try:
            normalized_scopes = oauth_scopes.normalize_scopes(allowed_scopes)
        except KeyError:
            # This should never fire: it implies that CAS issued a scope name not in the master list of scopes
            raise exceptions.APIException('OAuth2 token specifies unrecognized scope. User token specifies '
                                          'the following scopes: {}'.format(', '.join(allowed_scopes)))

        return required_scopes.issubset(normalized_scopes)
Exemplo n.º 11
0
def check_access(node, auth, action, cas_resp):
    """Verify that user can perform requested action on resource. Raise appropriate
    error code if action cannot proceed.
    """
    permission = permission_map.get(action, None)
    if permission is None:
        raise HTTPError(httplib.BAD_REQUEST)

    if cas_resp:
        if permission == 'read':
            if node.is_public:
                return True
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_READ
        else:
            required_scope = oauth_scopes.CoreScopes.NODE_FILE_WRITE
        if not cas_resp.authenticated \
           or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']):
            raise HTTPError(httplib.FORBIDDEN)

    if permission == 'read' and node.can_view(auth):
        return True
    if permission == 'write' and node.can_edit(auth):
        return True

    # Users attempting to register projects with components might not have
    # `write` permissions for all components. This will result in a 403 for
    # all `copyto` actions as well as `copyfrom` actions if the component
    # in question is not public. To get around this, we have to recursively
    # check the node's parent node to determine if they have `write`
    # permissions up the stack.
    # TODO(hrybacki): is there a way to tell if this is for a registration?
    # All nodes being registered that receive the `copyto` action will have
    # `node.is_registration` == True. However, we have no way of telling if
    # `copyfrom` actions are originating from a node being registered.
    # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
    if action == 'copyfrom' or (action == 'copyto' and node.is_registration):
        parent = node.parent_node
        while parent:
            if parent.can_edit(auth):
                return True
            parent = parent.parent_node

    # Users with the PREREG_ADMIN_TAG should be allowed to download files
    # from prereg challenge draft registrations.
    try:
        prereg_schema = MetaSchema.find_one(
            Q('name', 'eq', 'Prereg Challenge') &
            Q('schema_version', 'eq', 2)
        )
        allowed_nodes = [node] + node.parents
        prereg_draft_registration = DraftRegistration.find(
            Q('branched_from', 'in', [n._id for n in allowed_nodes]) &
            Q('registration_schema', 'eq', prereg_schema)
        )
        if action == 'download' and \
                    auth.user is not None and \
                    prereg_draft_registration.count() > 0 and \
                    settings.PREREG_ADMIN_TAG in auth.user.system_tags:
            return True
    except NoResultsFound:
        pass

    raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)
Exemplo n.º 12
0
 def get_serializer_class(self):
     if self.request.auth:
         scopes = self.request.auth.attributes['accessTokenScope']
         if (CoreScopes.USER_EMAIL_READ in normalize_scopes(scopes) and self.request.user == self.get_user()):
             return ReadEmailUserDetailSerializer
     return UserDetailSerializer
Exemplo n.º 13
0
def check_access(node, auth, action, cas_resp):
    """Verify that user can perform requested action on resource. Raise appropriate
    error code if action cannot proceed.
    """
    permission = permission_map.get(action, None)
    if permission is None:
        raise HTTPError(httplib.BAD_REQUEST)

    if cas_resp:
        if permission == 'read':
            if node.can_view_files(auth=None):
                return True
            required_scope = node.file_read_scope
        else:
            required_scope = node.file_write_scope

        if not cas_resp.authenticated \
           or required_scope not in oauth_scopes.normalize_scopes(cas_resp.attributes['accessTokenScope']):
            raise HTTPError(httplib.FORBIDDEN)

    if permission == 'read':
        if node.can_view_files(auth):
            return True
        # The user may have admin privileges on a parent node, in which
        # case they should have read permissions
        if getattr(node, 'is_registration', False) and node.registered_from.can_view(auth):
            return True
    if permission == 'write' and node.can_edit(auth):
        return True

    # Users attempting to register projects with components might not have
    # `write` permissions for all components. This will result in a 403 for
    # all `upload` actions as well as `copyfrom` actions if the component
    # in question is not public. To get around this, we have to recursively
    # check the node's parent node to determine if they have `write`
    # permissions up the stack.
    # TODO(hrybacki): is there a way to tell if this is for a registration?
    # All nodes being registered that receive the `upload` action will have
    # `node.is_registration` == True. However, we have no way of telling if
    # `copyfrom` actions are originating from a node being registered.
    # TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
    if isinstance(node, AbstractNode):
        if action == 'copyfrom' or (action == 'upload' and node.is_registration):
            parent = node.parent_node
            while parent:
                if parent.can_edit(auth):
                    return True
                parent = parent.parent_node

        # Users with the prereg admin permission should be allowed to download files
        # from prereg challenge draft registrations.
        try:
            prereg_schema = RegistrationSchema.objects.get(name='Prereg Challenge', schema_version=2)
            allowed_nodes = [node] + node.parents
            prereg_draft_registration = DraftRegistration.objects.filter(
                branched_from__in=allowed_nodes,
                registration_schema=prereg_schema
            )
            if action == 'download' and \
                        auth.user is not None and \
                        prereg_draft_registration.count() > 0 and \
                        auth.user.has_perm('osf.administer_prereg'):
                return True
        except RegistrationSchema.DoesNotExist:
            pass

    raise HTTPError(httplib.FORBIDDEN if auth.user else httplib.UNAUTHORIZED)