def test_from_kwargs(self): user = UserFactory() request_args = {'view_only': 'mykey'} kwargs = {'user': user} auth_obj = Auth.from_kwargs(request_args, kwargs) assert_equal(auth_obj.user, user) assert_equal(auth_obj.private_key, request_args['view_only'])
def wrapped(*args, **kwargs): response = None _inject_nodes(kwargs) node = kwargs['node'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user if user is not None: user.update_date_last_access() key = request.args.get('view_only', '').strip('/') #if not login user check if the key is valid or the other privilege kwargs['auth'].private_key = key if not include_view_only_anon: from osf.models import PrivateLink try: link_anon = PrivateLink.objects.filter(key=key).values_list('anonymous', flat=True).get() except PrivateLink.DoesNotExist: link_anon = None if not node.is_public or not include_public: if not include_view_only_anon and link_anon: if not check_can_access(node=node, user=user): raise HTTPError(http.UNAUTHORIZED) elif key not in node.private_link_keys_active: if not check_can_access(node=node, user=user, key=key): redirect_url = check_key_expired(key=key, node=node, url=request.url) if request.headers.get('Content-Type') == 'application/json': raise HTTPError(http.UNAUTHORIZED) else: response = redirect(cas.get_login_url(redirect_url)) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): response = None kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs) node = kwargs['node'] or kwargs['project'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user if 'api_node' in kwargs: api_node = kwargs['api_node'] else: api_node = get_api_key() kwargs['api_node'] = api_node key = request.args.get('view_only', '').strip('/') #if not login user check if the key is valid or the other privilege kwargs['auth'].private_key = key if not node.is_public or not include_public: if key not in node.private_link_keys_active: if not check_can_access( node=node, user=user, api_node=api_node, key=key): url = '/login/?next={0}'.format(request.path) redirect_url = check_key_expired(key=key, node=node, url=url) response = redirect(redirect_url) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): response = None kwargs['project'], kwargs['node'] = _kwargs_to_nodes(kwargs) node = kwargs['node'] or kwargs['project'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user if 'api_node' in kwargs: api_node = kwargs['api_node'] else: api_node = get_api_key() kwargs['api_node'] = api_node key = request.args.get('view_only', '').strip('/') #if not login user check if the key is valid or the other privilege kwargs['auth'].private_key = key if not node.is_public or not include_public: if key not in node.private_link_keys_active: if not check_can_access(node=node, user=user, api_node=api_node, key=key): url = '/login/?next={0}'.format(request.path) redirect_url = check_key_expired(key=key, node=node, url=url) response = redirect(redirect_url) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): response = None _inject_nodes(kwargs) node = kwargs['node'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user key = request.args.get('view_only', '').strip('/') #if not login user check if the key is valid or the other privilege kwargs['auth'].private_key = key link_anon = None if not include_view_only_anon: from website.models import PrivateLink try: link_anon = PrivateLink.find_one(Q('key', 'eq', key)).anonymous except ModularOdmException: pass if not node.is_public or not include_public: if not include_view_only_anon and link_anon: if not check_can_access(node=node, user=user): raise HTTPError(http.UNAUTHORIZED) elif key not in node.private_link_keys_active: if not check_can_access(node=node, user=user, key=key): redirect_url = check_key_expired(key=key, node=node, url=request.url) if request.headers.get('Content-Type') == 'application/json': raise HTTPError(http.UNAUTHORIZED) else: response = redirect(cas.get_login_url(redirect_url)) return response or func(*args, **kwargs)
def _view_registries_landing_page(campaign=None, **kwargs): """Landing page for the various registrations""" auth = kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) is_logged_in = kwargs['auth'].logged_in if is_logged_in: # Using contributor_to instead of contributor_to_or_group_member. # You need to be an admin contributor to register a node registerable_nodes = [ node for node in auth.user.contributor_to if node.has_permission(user=auth.user, permission=ADMIN) ] has_projects = bool(registerable_nodes) else: has_projects = False if campaign == 'registered_report': campaign_url_param = 'osf-registered-reports' elif campaign == 'prereg_challenge' or campaign == 'prereg': campaign_url_param = 'prereg' else: campaign_url_param = '' return { 'is_logged_in': is_logged_in, 'has_draft_registrations': bool(utils.drafts_for_user(auth.user, campaign)), 'has_projects': has_projects, 'campaign_long': utils.REG_CAMPAIGNS.get(campaign), 'campaign_short': campaign, 'sign_up_url': util.web_url_for('auth_register', _absolute=True, campaign=campaign_url_param, next=request.url), }
def wrapped(*args, **kwargs): response = None _inject_nodes(kwargs) node = kwargs['node'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user key = request.args.get('view_only', '').strip('/') #if not login user check if the key is valid or the other privilege kwargs['auth'].private_key = key if not node.is_public or not include_public: if key not in node.private_link_keys_active: if not check_can_access(node=node, user=user, key=key): redirect_url = check_key_expired(key=key, node=node, url=request.url) if request.headers.get( 'Content-Type') == 'application/json': raise HTTPError(http.UNAUTHORIZED) else: response = redirect( cas.get_login_url(redirect_url)) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): _inject_nodes(kwargs) kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) response = check_contributor_auth(kwargs['node'], kwargs['auth'], include_public, include_view_only_anon) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): response = None target = None guid = Guid.load(kwargs.get('guid')) if guid: target = getattr(guid, 'referent', None) else: _inject_nodes(kwargs) target = target or kwargs.get('node') kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) response = check_contributor_auth(target, kwargs['auth'], include_public, include_view_only_anon, include_groups) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): response = None target = None guid = Guid.load(kwargs.get('guid')) if guid: target = getattr(guid, 'referent', None) else: _inject_nodes(kwargs) target = target or kwargs.get('node') kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) response = check_contributor_auth(target, kwargs['auth'], include_public, include_view_only_anon) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): # Ensure `project` and `node` kwargs _inject_nodes(kwargs) node = kwargs["node"] kwargs["auth"] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs["auth"].user # User must be logged in if user is None: raise HTTPError(http.UNAUTHORIZED) # User must have permissions if not node.has_permission(user, permission): raise HTTPError(http.FORBIDDEN) # Call view function return func(*args, **kwargs)
def wrapped(*args, **kwargs): # Ensure `project` and `node` kwargs _inject_nodes(kwargs) node = kwargs['node'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user # User must be logged in if user is None: raise HTTPError(http.UNAUTHORIZED) # User must have permissions if not node.has_permission(user, permission): raise HTTPError(http.FORBIDDEN) # Call view function return func(*args, **kwargs)
def wrapped(*args, **kwargs): response = None _inject_nodes(kwargs) node = kwargs['node'] kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user key = request.args.get('view_only', '').strip('/') #if not login user check if the key is valid or the other privilege kwargs['auth'].private_key = key if not node.is_public or not include_public: if key not in node.private_link_keys_active: if not check_can_access(node=node, user=user, key=key): redirect_url = check_key_expired(key=key, node=node, url=request.url) response = redirect(cas.get_login_url(redirect_url)) return response or func(*args, **kwargs)
def wrapped(*args, **kwargs): # Ensure `project` and `node` kwargs if kwargs.get('nid') or kwargs.get('pid'): _inject_nodes(kwargs) target = kwargs.get('node') or getattr(Guid.load(kwargs.get('guid')), 'referent', None) kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs['auth'].user # User must be logged in if user is None: raise HTTPError(http.UNAUTHORIZED) # User must have permissions if not target.has_permission(user, permission): raise HTTPError(http.FORBIDDEN) # Call view function return func(*args, **kwargs)
def _view_registries_landing_page(campaign=None, **kwargs): """Landing page for the various registrations""" auth = kwargs['auth'] = Auth.from_kwargs(request.args.to_dict(), kwargs) is_logged_in = kwargs['auth'].logged_in if is_logged_in: registerable_nodes = [ node for node in auth.user.contributor_to if node.has_permission(user=auth.user, permission='admin') ] has_projects = bool(registerable_nodes) else: has_projects = False return { 'is_logged_in': is_logged_in, 'has_draft_registrations': bool(utils.drafts_for_user(auth.user, campaign)), 'has_projects': has_projects, 'campaign_long': utils.REG_CAMPAIGNS.get(campaign), 'campaign_short': campaign }
def wrapped(*args, **kwargs): response = None _inject_nodes(kwargs) node = kwargs["node"] kwargs["auth"] = Auth.from_kwargs(request.args.to_dict(), kwargs) user = kwargs["auth"].user key = request.args.get("view_only", "").strip("/") # if not login user check if the key is valid or the other privilege kwargs["auth"].private_key = key if not node.is_public or not include_public: if key not in node.private_link_keys_active: if not check_can_access(node=node, user=user, key=key): redirect_url = check_key_expired(key=key, node=node, url=request.url) if request.headers.get("Content-Type") == "application/json": raise HTTPError(http.UNAUTHORIZED) else: response = redirect(cas.get_login_url(redirect_url)) return response or func(*args, **kwargs)
def resolve_guid(guid, suffix=None): """Load GUID by primary key, look up the corresponding view function in the routing table, and return the return value of the view function without changing the URL. :param str guid: GUID primary key :param str suffix: Remainder of URL after the GUID :return: Return value of proxied view function """ try: # Look up guid_object = Guid.load(guid) except KeyError as e: if e.message == 'osfstorageguidfile': # Used when an old detached OsfStorageGuidFile object is accessed raise HTTPError(http.NOT_FOUND) else: raise e if guid_object: # verify that the object implements a GuidStoredObject-like interface. If a model # was once GuidStoredObject-like but that relationship has changed, it's # possible to have referents that are instances of classes that don't # have a deep_url attribute or otherwise don't behave as # expected. if not hasattr(guid_object.referent, 'deep_url'): sentry.log_message( 'Guid resolved to an object with no deep_url', dict(guid=guid) ) raise HTTPError(http.NOT_FOUND) referent = guid_object.referent if referent is None: logger.error('Referent of GUID {0} not found'.format(guid)) raise HTTPError(http.NOT_FOUND) if not referent.deep_url: raise HTTPError(http.NOT_FOUND) # Handle file `/download` shortcut with supported types. if suffix and suffix.rstrip('/').lower() == 'download': file_referent = None if isinstance(referent, PreprintService) and referent.primary_file: if not referent.is_published: # TODO: Ideally, permissions wouldn't be checked here. # This is necessary to prevent a logical inconsistency with # the routing scheme - if a preprint is not published, only # admins and moderators should be able to know it exists. auth = Auth.from_kwargs(request.args.to_dict(), {}) group_helper = GroupHelper(referent.provider) admin_group = group_helper.get_group('admin') mod_group = group_helper.get_group('moderator') # Check if user isn't a nonetype or that the user has admin/moderator permissions if auth.user is None or not (referent.node.has_permission(auth.user, permissions.ADMIN) or (mod_group.user_set.all() | admin_group.user_set.all()).filter(id=auth.user.id).exists()): raise HTTPError(http.NOT_FOUND) file_referent = referent.primary_file elif isinstance(referent, BaseFileNode) and referent.is_file: file_referent = referent if file_referent: # Extend `request.args` adding `action=download`. request.args = request.args.copy() request.args.update({'action': 'download'}) # Do not include the `download` suffix in the url rebuild. url = _build_guid_url(urllib.unquote(file_referent.deep_url)) return proxy_url(url) # Handle Ember Applications if isinstance(referent, PreprintService): if referent.provider.domain_redirect_enabled: # This route should always be intercepted by nginx for the branded domain, # w/ the exception of `<guid>/download` handled above. return redirect(referent.absolute_url, http.MOVED_PERMANENTLY) if PROXY_EMBER_APPS: resp = requests.get(EXTERNAL_EMBER_APPS['preprints']['server'], stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT) return Response(stream_with_context(resp.iter_content()), resp.status_code) return send_from_directory(preprints_dir, 'index.html') if isinstance(referent, BaseFileNode) and referent.is_file and referent.node.is_quickfiles: if referent.is_deleted: raise HTTPError(http.GONE) if PROXY_EMBER_APPS: resp = requests.get(EXTERNAL_EMBER_APPS['ember_osf_web']['server'], stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT) return Response(stream_with_context(resp.iter_content()), resp.status_code) return send_from_directory(ember_osf_web_dir, 'index.html') if isinstance(referent, Node) and not referent.is_registration and suffix: page = suffix.strip('/').split('/')[0] flag_name = 'ember_project_{}_page'.format(page) request.user = _get_current_user() or MockUser() if waffle.flag_is_active(request, flag_name): use_ember_app() url = _build_guid_url(urllib.unquote(referent.deep_url), suffix) return proxy_url(url) # GUID not found; try lower-cased and redirect if exists guid_object_lower = Guid.load(guid.lower()) if guid_object_lower: return redirect( _build_guid_url(guid.lower(), suffix) ) # GUID not found raise HTTPError(http.NOT_FOUND)
def resolve_guid(guid, suffix=None): """Load GUID by primary key, look up the corresponding view function in the routing table, and return the return value of the view function without changing the URL. :param str guid: GUID primary key :param str suffix: Remainder of URL after the GUID :return: Return value of proxied view function """ try: # Look up guid_object = Guid.load(guid) except KeyError as e: if e.message == 'osfstorageguidfile': # Used when an old detached OsfStorageGuidFile object is accessed raise HTTPError(http.NOT_FOUND) else: raise e if guid_object: # verify that the object implements a GuidStoredObject-like interface. If a model # was once GuidStoredObject-like but that relationship has changed, it's # possible to have referents that are instances of classes that don't # have a deep_url attribute or otherwise don't behave as # expected. if not hasattr(guid_object.referent, 'deep_url'): sentry.log_message( 'Guid resolved to an object with no deep_url', dict(guid=guid) ) raise HTTPError(http.NOT_FOUND) referent = guid_object.referent if referent is None: logger.error('Referent of GUID {0} not found'.format(guid)) raise HTTPError(http.NOT_FOUND) if not referent.deep_url: raise HTTPError(http.NOT_FOUND) # Handle file `/download` shortcut with supported types. if suffix and suffix.rstrip('/').lower() == 'download': file_referent = None if isinstance(referent, PreprintService) and referent.primary_file: if not referent.is_published: # TODO: Ideally, permissions wouldn't be checked here. # This is necessary to prevent a logical inconsistency with # the routing scheme - if a preprint is not published, only # admins should be able to know it exists. auth = Auth.from_kwargs(request.args.to_dict(), {}) if not referent.node.has_permission(auth.user, permissions.ADMIN): raise HTTPError(http.NOT_FOUND) file_referent = referent.primary_file elif isinstance(referent, BaseFileNode) and referent.is_file: file_referent = referent if file_referent: # Extend `request.args` adding `action=download`. request.args = request.args.copy() request.args.update({'action': 'download'}) # Do not include the `download` suffix in the url rebuild. url = _build_guid_url(urllib.unquote(file_referent.deep_url)) return proxy_url(url) # Handle Ember Applications if isinstance(referent, PreprintService): if referent.provider.domain_redirect_enabled: # This route should always be intercepted by nginx for the branded domain, # w/ the exception of `<guid>/download` handled above. return redirect(referent.absolute_url, http.MOVED_PERMANENTLY) return send_from_directory(preprints_dir, 'index.html') url = _build_guid_url(urllib.unquote(referent.deep_url), suffix) return proxy_url(url) # GUID not found; try lower-cased and redirect if exists guid_object_lower = Guid.load(guid.lower()) if guid_object_lower: return redirect( _build_guid_url(guid.lower(), suffix) ) # GUID not found raise HTTPError(http.NOT_FOUND)
def resolve_guid(guid, suffix=None): """Load GUID by primary key, look up the corresponding view function in the routing table, and return the return value of the view function without changing the URL. :param str guid: GUID primary key :param str suffix: Remainder of URL after the GUID :return: Return value of proxied view function """ try: # Look up guid_object = Guid.load(guid) except KeyError as e: if e.message == 'osfstorageguidfile': # Used when an old detached OsfStorageGuidFile object is accessed raise HTTPError(http.NOT_FOUND) else: raise e if guid_object: # verify that the object implements a GuidStoredObject-like interface. If a model # was once GuidStoredObject-like but that relationship has changed, it's # possible to have referents that are instances of classes that don't # have a deep_url attribute or otherwise don't behave as # expected. if not hasattr(guid_object.referent, 'deep_url'): sentry.log_message( 'Guid resolved to an object with no deep_url', dict(guid=guid) ) raise HTTPError(http.NOT_FOUND) referent = guid_object.referent if referent is None: logger.error('Referent of GUID {0} not found'.format(guid)) raise HTTPError(http.NOT_FOUND) if not referent.deep_url: raise HTTPError(http.NOT_FOUND) # Handle file `/download` shortcut with supported types. if suffix and suffix.rstrip('/').lower() == 'download': file_referent = None if isinstance(referent, Preprint) and referent.primary_file: file_referent = referent.primary_file elif isinstance(referent, BaseFileNode) and referent.is_file: file_referent = referent if file_referent: if isinstance(file_referent.target, Preprint) and not file_referent.target.is_published: # TODO: Ideally, permissions wouldn't be checked here. # This is necessary to prevent a logical inconsistency with # the routing scheme - if a preprint is not published, only # admins and moderators should be able to know it exists. auth = Auth.from_kwargs(request.args.to_dict(), {}) # Check if user isn't a nonetype or that the user has admin/moderator/superuser permissions if auth.user is None or not (auth.user.has_perm('view_submissions', file_referent.target.provider) or file_referent.target.has_permission(auth.user, permissions.ADMIN)): raise HTTPError(http.NOT_FOUND) # Extend `request.args` adding `action=download`. request.args = request.args.copy() request.args.update({'action': 'download'}) # Do not include the `download` suffix in the url rebuild. url = _build_guid_url(urllib.unquote(file_referent.deep_url)) return proxy_url(url) # Handle Ember Applications if isinstance(referent, Preprint): if referent.provider.domain_redirect_enabled: # This route should always be intercepted by nginx for the branded domain, # w/ the exception of `<guid>/download` handled above. return redirect(referent.absolute_url, http.MOVED_PERMANENTLY) if PROXY_EMBER_APPS: resp = requests.get(EXTERNAL_EMBER_APPS['preprints']['server'], stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT) return Response(stream_with_context(resp.iter_content()), resp.status_code) return send_from_directory(preprints_dir, 'index.html') if isinstance(referent, BaseFileNode) and referent.is_file and (getattr(referent.target, 'is_quickfiles', False)): if referent.is_deleted: raise HTTPError(http.GONE) if PROXY_EMBER_APPS: resp = requests.get(EXTERNAL_EMBER_APPS['ember_osf_web']['server'], stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT) return Response(stream_with_context(resp.iter_content()), resp.status_code) return send_from_directory(ember_osf_web_dir, 'index.html') if isinstance(referent, Registration) and ( not suffix or suffix.rstrip('/').lower() in ('comments', 'links', 'components') ): if flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE): # Route only the base detail view to ember if PROXY_EMBER_APPS: resp = requests.get(EXTERNAL_EMBER_APPS['ember_osf_web']['server'], stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT) return Response(stream_with_context(resp.iter_content()), resp.status_code) return send_from_directory(registries_dir, 'index.html') url = _build_guid_url(urllib.unquote(referent.deep_url), suffix) return proxy_url(url) # GUID not found; try lower-cased and redirect if exists guid_object_lower = Guid.load(guid.lower()) if guid_object_lower: return redirect( _build_guid_url(guid.lower(), suffix) ) # GUID not found raise HTTPError(http.NOT_FOUND)
def resolve_guid(guid, suffix=None): """Load GUID by primary key, look up the corresponding view function in the routing table, and return the return value of the view function without changing the URL. :param str guid: GUID primary key :param str suffix: Remainder of URL after the GUID :return: Return value of proxied view function """ try: # Look up guid_object = Guid.load(guid) except KeyError as e: if e.message == 'osfstorageguidfile': # Used when an old detached OsfStorageGuidFile object is accessed raise HTTPError(http.NOT_FOUND) else: raise e if guid_object: # verify that the object implements a GuidStoredObject-like interface. If a model # was once GuidStoredObject-like but that relationship has changed, it's # possible to have referents that are instances of classes that don't # have a deep_url attribute or otherwise don't behave as # expected. if not hasattr(guid_object.referent, 'deep_url'): sentry.log_message( 'Guid `{}` resolved to an object with no deep_url'.format( guid)) raise HTTPError(http.NOT_FOUND) referent = guid_object.referent if referent is None: logger.error('Referent of GUID {0} not found'.format(guid)) raise HTTPError(http.NOT_FOUND) if not referent.deep_url: raise HTTPError(http.NOT_FOUND) # Handle file `/download` shortcut with supported types. if suffix and suffix.rstrip('/').lower() == 'download': file_referent = None if isinstance(referent, PreprintService) and referent.primary_file: if not referent.is_published: # TODO: Ideally, permissions wouldn't be checked here. # This is necessary to prevent a logical inconsistency with # the routing scheme - if a preprint is not published, only # admins should be able to know it exists. auth = Auth.from_kwargs(request.args.to_dict(), {}) if not referent.node.has_permission( auth.user, permissions.ADMIN): raise HTTPError(http.NOT_FOUND) file_referent = referent.primary_file elif isinstance(referent, BaseFileNode) and referent.is_file: file_referent = referent if file_referent: # Extend `request.args` adding `action=download`. request.args = request.args.copy() request.args.update({'action': 'download'}) # Do not include the `download` suffix in the url rebuild. url = _build_guid_url(urllib.unquote(file_referent.deep_url)) return proxy_url(url) # Handle Ember Applications if isinstance(referent, PreprintService): if referent.provider.domain_redirect_enabled: # This route should always be intercepted by nginx for the branded domain, # w/ the exception of `<guid>/download` handled above. return redirect(referent.absolute_url, http.MOVED_PERMANENTLY) return send_from_directory(preprints_dir, 'index.html') url = _build_guid_url(urllib.unquote(referent.deep_url), suffix) return proxy_url(url) # GUID not found; try lower-cased and redirect if exists guid_object_lower = Guid.load(guid.lower()) if guid_object_lower: return redirect(_build_guid_url(guid.lower(), suffix)) # GUID not found raise HTTPError(http.NOT_FOUND)