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)
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
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)
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']))
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)
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)
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)
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)
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)
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)