def setUp(self): def dummy_view(): return {} def dummy_guid_project_view(): return {} def dummy_guid_profile_view(): return {} self.app = Flask(__name__) api_rule = Rule(['/api/v1/<pid>/', '/api/v1/<pid>/component/<nid>/'], 'get', dummy_view, json_renderer) web_rule = Rule(['/<pid>/', '/<pid>/component/<nid>/'], 'get', dummy_view, OsfWebRenderer) web_guid_project_rule = Rule([ '/project/<pid>/', '/project/<pid>/node/<nid>/', ], 'get', dummy_guid_project_view, OsfWebRenderer) web_guid_profile_rule = Rule([ '/profile/<pid>/', ], 'get', dummy_guid_profile_view, OsfWebRenderer) process_rules( self.app, [api_rule, web_rule, web_guid_project_rule, web_guid_profile_rule])
def test_url_for_simple(self): r = Rule(["/project/"], "get", view_func_or_data=dummy_view, renderer=json_renderer) process_rules(self.app, [r]) with self.app.test_request_context(): assert_equal(url_for("JSONRenderer__dummy_view"), "/project/")
def test_error_handling_with_message(self): rule = Rule(['/error/'], 'get', error_with_msg, renderer=json_renderer) process_rules(self.app, [rule]) res = self.wt.get('/error/', expect_errors=True) assert_equal(res.status_code, 400) data = res.json assert_equal(data['message_short'], 'Invalid') assert_equal(data['message_long'], 'Invalid request')
def test_url_for_simple(self): r = Rule(['/project/'], 'get', view_func_or_data=dummy_view, renderer=json_renderer) process_rules(self.app, [r]) with self.app.test_request_context(): assert_equal(url_for('JSONRenderer__dummy_view'), '/project/')
def test_url_for_with_prefix(self): api_rule = Rule(['/project/'], 'get', view_func_or_data=dummy_view3, renderer=json_renderer) process_rules(self.app, [api_rule], prefix='/api/v1') with self.app.test_request_context(): assert_equal(url_for('JSONRenderer__dummy_view3'), '/api/v1/project/')
def test_url_for_with_prefix(self): api_rule = Rule(["/project/"], "get", view_func_or_data=dummy_view3, renderer=json_renderer) process_rules(self.app, [api_rule], prefix="/api/v1") with self.app.test_request_context(): assert_equal(url_for("JSONRenderer__dummy_view3"), "/api/v1/project/")
def test_url_for_with_argument(self): r = Rule(['/project/<pid>/'], "get", view_func_or_data=dummy_view2, renderer=json_renderer) process_rules(self.app, [r]) with self.app.test_request_context(): assert_equal(url_for("JSONRenderer__dummy_view2", pid=123), "/project/123/")
def _make_rule(self, **kwargs): def vf(): return {} return Rule( kwargs.get('routes', [ '/', ]), kwargs.get('methods', [ 'GET', ]), kwargs.get('view_func_or_data', vf), kwargs.get('renderer', json_renderer), kwargs.get('view_kwargs'), )
from framework.routing import Rule, json_renderer from . import views settings_routes = { 'rules': [ # OAuth: General Rule([ '/settings/twofactor/', ], 'post', views.user_settings, json_renderer), ], 'prefix': '/api/v1', }
from framework.routing import Rule, json_renderer from website.routes import OsfWebRenderer from . import views api_routes = { 'rules': [ Rule( '/settings/dataverse/', 'get', views.dataverse_user_config_get, json_renderer, ), Rule( '/settings/dataverse/accounts/', 'post', views.dataverse_add_user_account, json_renderer, ), Rule( '/settings/dataverse/accounts/', 'get', views.dataverse_account_list, json_renderer, ), Rule( [ '/project/<pid>/dataverse/settings/', '/project/<pid>/node/<nid>/dataverse/settings/', ], 'get',
# -*- coding: utf-8 -*- """Box addon routes.""" from framework.routing import Rule, json_renderer from website.addons.box import views auth_routes = { 'rules': [ ##### OAuth ##### Rule( '/oauth/connect/box/', 'get', views.auth. box_oauth_start, # Use same view func as node oauth start json_renderer, endpoint_suffix='_user' # but add a suffix for url_for ), Rule( '/oauth/callback/box/', 'get', views.auth.box_oauth_finish, json_renderer, ), Rule( '/oauth/accounts/box/', 'delete', views.auth.box_oauth_delete_user, json_renderer, ), ],
# encoding: utf-8 from framework.routing import Rule, json_renderer from website.addons.osfstorage import views api_routes = { 'prefix': '/api/v1', 'rules': [ Rule( [ '/project/<pid>/osfstorage/', '/project/<pid>/node/<nid>/osfstorage/', '/project/<pid>/osfstorage/<fid>/', '/project/<pid>/node/<nid>/osfstorage/<fid>/', ], 'get', views.osfstorage_get_metadata, json_renderer, ), Rule( [ '/project/<pid>/osfstorage/<fid>/', '/project/<pid>/node/<nid>/osfstorage/<fid>/', ], 'delete', views.osfstorage_delete, json_renderer, ), Rule(
# -*- coding: utf-8 -*- """Box addon routes.""" from framework.routing import Rule, json_renderer from website.addons.box import views api_routes = { 'rules': [ Rule( [ '/settings/box/accounts/', ], 'get', views.box_get_user_settings, json_renderer, ), Rule( [ '/project/<pid>/box/settings/', '/project/<pid>/node/<nid>/box/settings/' ], 'get', views.box_get_config, json_renderer, ), Rule( [ '/project/<pid>/box/settings/', '/project/<pid>/node/<nid>/box/settings/' ], 'put',
def make_url_map(app): """Set up all the routes for the OSF app. :param app: A Flask/Werkzeug app to bind the rules to. """ # Set default views to 404, using URL-appropriate renderers process_rules(app, [ Rule('/<path:_>', ['get', 'post'], HTTPError(http.NOT_FOUND), OsfWebRenderer('', render_mako_string)), Rule('/api/v1/<path:_>', ['get', 'post'], HTTPError(http.NOT_FOUND), json_renderer), ]) ### GUID ### process_rules(app, [ Rule( [ '/<guid>/', '/<guid>/<path:suffix>', ], ['get', 'post', 'put', 'patch', 'delete'], website_views.resolve_guid, notemplate, ), Rule( [ '/api/v1/<guid>/', '/api/v1/<guid>/<path:suffix>', ], ['get', 'post', 'put', 'patch', 'delete'], website_views.resolve_guid, json_renderer, ), ]) # Static files process_rules(app, [ Rule('/favicon.ico', 'get', favicon, json_renderer), Rule('/robots.txt', 'get', robots, json_renderer), ]) ### Base ### process_rules(app, [ Rule('/dashboard/', 'get', website_views.dashboard, OsfWebRenderer('dashboard.mako')), Rule('/reproducibility/', 'get', website_views.reproducibility, OsfWebRenderer('', render_mako_string)), Rule( '/about/', 'get', website_views.redirect_about, json_renderer, ), Rule( '/howosfworks/', 'get', website_views.redirect_howosfworks, json_renderer, ), Rule('/faq/', 'get', {}, OsfWebRenderer('public/pages/faq.mako')), Rule('/getting-started/', 'get', {}, OsfWebRenderer('public/pages/getting_started.mako')), Rule('/explore/', 'get', {}, OsfWebRenderer('public/explore.mako')), Rule(['/messages/', '/help/'], 'get', {}, OsfWebRenderer('public/comingsoon.mako')), Rule( '/view/<meeting>/', 'get', conference_views.conference_results, OsfWebRenderer('public/pages/meeting.mako'), ), Rule( '/view/<meeting>/plain/', 'get', conference_views.conference_results, OsfWebRenderer('public/pages/meeting_plain.mako'), endpoint_suffix='__plain', ), Rule( '/api/v1/view/<meeting>/', 'get', conference_views.conference_data, json_renderer, ), Rule( '/meetings/', 'get', conference_views.conference_view, OsfWebRenderer('public/pages/meeting_landing.mako'), ), Rule( '/presentations/', 'get', conference_views.redirect_to_meetings, json_renderer, ), Rule('/news/', 'get', {}, OsfWebRenderer('public/pages/news.mako')), ]) # Site-wide API routes process_rules(app, [ Rule( '/citations/styles/', 'get', citation_views.list_citation_styles, json_renderer, ), ], prefix='/api/v1') process_rules(app, [ Rule( [ '/project/<pid>/<addon>/settings/disable/', '/project/<pid>/node/<nid>/<addon>/settings/disable/', ], 'post', addon_views.disable_addon, json_renderer, ), Rule( '/profile/<uid>/<addon>/settings/', 'get', addon_views.get_addon_user_config, json_renderer, ), ], prefix='/api/v1') # OAuth process_rules(app, [ Rule( '/oauth/connect/<service_name>/', 'get', oauth_views.oauth_connect, json_renderer, ), Rule( '/oauth/callback/<service_name>/', 'get', oauth_views.oauth_callback, OsfWebRenderer('util/oauth_complete.mako'), ), ]) process_rules(app, [ Rule( [ '/oauth/accounts/<external_account_id>/', ], 'delete', oauth_views.oauth_disconnect, json_renderer, ) ], prefix='/api/v1') process_rules(app, [ Rule('/dashboard/get_nodes/', 'get', website_views.get_dashboard_nodes, json_renderer), Rule([ '/dashboard/<nid>', '/dashboard/', ], 'get', website_views.get_dashboard, json_renderer), ], prefix='/api/v1') ### Metadata ### process_rules(app, [ Rule( [ '/project/<pid>/comments/', '/project/<pid>/node/<nid>/comments/', ], 'get', project_views.comment.list_comments, json_renderer, ), Rule( [ '/project/<pid>/comments/discussion/', '/project/<pid>/node/<nid>/comments/discussion/', ], 'get', project_views.comment.comment_discussion, json_renderer, ), Rule( [ '/project/<pid>/comment/', '/project/<pid>/node/<nid>/comment/', ], 'post', project_views.comment.add_comment, json_renderer, ), Rule( [ '/project/<pid>/comment/<cid>/', '/project/<pid>/node/<nid>/comment/<cid>/', ], 'put', project_views.comment.edit_comment, json_renderer, ), Rule( [ '/project/<pid>/comment/<cid>/', '/project/<pid>/node/<nid>/comment/<cid>/', ], 'delete', project_views.comment.delete_comment, json_renderer, ), Rule( [ '/project/<pid>/comment/<cid>/undelete/', '/project/<pid>/node/<nid>/comment/<cid>/undelete/', ], 'put', project_views.comment.undelete_comment, json_renderer, ), Rule( [ '/project/<pid>/comments/timestamps/', '/project/<pid>/node/<nid>/comments/timestamps/', ], 'put', project_views.comment.update_comments_timestamp, json_renderer, ), Rule( [ '/project/<pid>/comment/<cid>/report/', '/project/<pid>/node/<nid>/comment/<cid>/report/', ], 'post', project_views.comment.report_abuse, json_renderer, ), Rule( [ '/project/<pid>/comment/<cid>/unreport/', '/project/<pid>/node/<nid>/comment/<cid>/unreport/', ], 'post', project_views.comment.unreport_abuse, json_renderer, ), Rule( [ '/project/<pid>/citation/', '/project/<pid>/node/<nid>/citation/', ], 'get', citation_views.node_citation, json_renderer, ), ], prefix='/api/v1') ### Forms ### process_rules(app, [ Rule('/forms/registration/', 'get', website_views.registration_form, json_renderer), Rule('/forms/signin/', 'get', website_views.signin_form, json_renderer), Rule('/forms/forgot_password/', 'get', website_views.forgot_password_form, json_renderer), Rule('/forms/reset_password/', 'get', website_views.reset_password_form, json_renderer), ], prefix='/api/v1') ### Discovery ### process_rules(app, [ Rule('/explore/activity/', 'get', discovery_views.activity, OsfWebRenderer('public/pages/active_nodes.mako', trust=False)), ]) ### Auth ### # Web process_rules( app, [ Rule( '/confirm/<uid>/<token>/', 'get', auth_views.confirm_email_get, # View will either redirect or display error message OsfWebRenderer('error.mako', render_mako_string)), Rule( '/resetpassword/<verification_key>/', ['get', 'post'], auth_views.reset_password, OsfWebRenderer('public/resetpassword.mako', render_mako_string)), # Resend confirmation URL linked to in CAS login page Rule('/resend/', ['get', 'post'], auth_views.resend_confirmation, OsfWebRenderer('resend.mako', render_mako_string)), # TODO: Remove `auth_register_post` Rule('/register/', 'post', auth_views.auth_register_post, OsfWebRenderer('public/login.mako')), Rule('/api/v1/register/', 'post', auth_views.register_user, json_renderer), Rule(['/login/', '/account/'], 'get', auth_views.auth_login, OsfWebRenderer('public/login.mako')), Rule('/login/first/', 'get', auth_views.auth_login, OsfWebRenderer('public/login.mako'), endpoint_suffix='__first', view_kwargs={'first': True}), Rule('/logout/', 'get', auth_views.auth_logout, notemplate), Rule('/forgotpassword/', 'get', auth_views.forgot_password_get, OsfWebRenderer('public/forgot_password.mako')), Rule('/forgotpassword/', 'post', auth_views.forgot_password_post, OsfWebRenderer('public/login.mako')), Rule(['/midas/', '/summit/', '/accountbeta/', '/decline/'], 'get', auth_views.auth_registerbeta, OsfWebRenderer('', render_mako_string)), Rule('/login/connected_tools/', 'get', landing_page_views.connected_tools, OsfWebRenderer('public/login_landing.mako')), Rule('/login/enriched_profile/', 'get', landing_page_views.enriched_profile, OsfWebRenderer('public/login_landing.mako')), ]) ### Profile ### # Web process_rules( app, [ Rule('/profile/', 'get', profile_views.profile_view, OsfWebRenderer('profile.mako', trust=False)), Rule('/profile/<uid>/', 'get', profile_views.profile_view_id, OsfWebRenderer('profile.mako', trust=False)), Rule(["/user/merge/"], 'get', auth_views.merge_user_get, OsfWebRenderer("merge_accounts.mako", trust=False)), Rule(["/user/merge/"], 'post', auth_views.merge_user_post, OsfWebRenderer("merge_accounts.mako", trust=False)), # Route for claiming and setting email and password. # Verification token must be querystring argument Rule(['/user/<uid>/<pid>/claim/'], ['get', 'post'], project_views.contributor.claim_user_form, OsfWebRenderer('claim_account.mako', trust=False)), Rule(['/user/<uid>/<pid>/claim/verify/<token>/'], ['get', 'post'], project_views.contributor.claim_user_registered, OsfWebRenderer('claim_account_registered.mako', trust=False)), Rule( '/settings/', 'get', profile_views.user_profile, OsfWebRenderer('profile/settings.mako', trust=False), ), Rule( '/settings/account/', 'get', profile_views.user_account, OsfWebRenderer('profile/account.mako', trust=False), ), Rule( '/settings/account/password', 'post', profile_views.user_account_password, OsfWebRenderer('profile/account.mako', trust=False), ), Rule( '/settings/addons/', 'get', profile_views.user_addons, OsfWebRenderer('profile/addons.mako', trust=False), ), Rule( '/settings/notifications/', 'get', profile_views.user_notifications, OsfWebRenderer('profile/notifications.mako', trust=False), ), # TODO: Uncomment once outstanding issues with this feature are addressed # Rule( # '/@<twitter_handle>/', # 'get', # profile_views.redirect_to_twitter, # OsfWebRenderer('error.mako', render_mako_string, trust=False) # ), ]) # API process_rules( app, [ Rule('/profile/', 'get', profile_views.profile_view, json_renderer), Rule('/profile/', 'put', profile_views.update_user, json_renderer), Rule('/resend/', 'put', profile_views.resend_confirmation, json_renderer), Rule('/profile/<uid>/', 'get', profile_views.profile_view_id, json_renderer), # Used by profile.html Rule('/profile/<uid>/edit/', 'post', profile_views.edit_profile, json_renderer), Rule('/profile/<uid>/public_projects/', 'get', profile_views.get_public_projects, json_renderer), Rule('/profile/<uid>/public_components/', 'get', profile_views.get_public_components, json_renderer), Rule('/profile/<user_id>/summary/', 'get', profile_views.get_profile_summary, json_renderer), Rule('/user/<uid>/<pid>/claim/email/', 'post', project_views.contributor.claim_user_post, json_renderer), Rule( '/profile/export/', 'post', profile_views.request_export, json_renderer, ), Rule( '/profile/deactivate/', 'post', profile_views.request_deactivation, json_renderer, ), Rule( [ '/profile/gravatar/', '/users/gravatar/', '/profile/gravatar/<size>', '/users/gravatar/<size>', ], 'get', profile_views.current_user_gravatar, json_renderer, ), Rule( [ '/profile/<uid>/gravatar/', '/users/<uid>/gravatar/', '/profile/<uid>/gravatar/<size>', '/users/<uid>/gravatar/<size>', ], 'get', profile_views.get_gravatar, json_renderer, ), # Rules for user profile configuration Rule('/settings/names/', 'get', profile_views.serialize_names, json_renderer), Rule('/settings/names/', 'put', profile_views.unserialize_names, json_renderer), Rule('/settings/names/impute/', 'get', profile_views.impute_names, json_renderer), Rule( [ '/settings/social/', '/settings/social/<uid>/', ], 'get', profile_views.serialize_social, json_renderer, ), Rule( [ '/settings/jobs/', '/settings/jobs/<uid>/', ], 'get', profile_views.serialize_jobs, json_renderer, ), Rule( [ '/settings/schools/', '/settings/schools/<uid>/', ], 'get', profile_views.serialize_schools, json_renderer, ), Rule([ '/settings/social/', '/settings/social/<uid>/', ], 'put', profile_views.unserialize_social, json_renderer), Rule([ '/settings/jobs/', '/settings/jobs/<uid>/', ], 'put', profile_views.unserialize_jobs, json_renderer), Rule([ '/settings/schools/', '/settings/schools/<uid>/', ], 'put', profile_views.unserialize_schools, json_renderer), ], prefix='/api/v1', ) ### Search ### # Web process_rules(app, [ Rule('/search/', 'get', {}, OsfWebRenderer('search.mako')), Rule('/share/', 'get', {}, OsfWebRenderer('share_search.mako')), Rule('/share/registration/', 'get', {'register': settings.SHARE_REGISTRATION_URL}, OsfWebRenderer('share_registration.mako')), Rule('/share/help/', 'get', {'help': settings.SHARE_API_DOCS_URL}, OsfWebRenderer('share_api_docs.mako')), Rule('/share_dashboard/', 'get', {}, OsfWebRenderer('share_dashboard.mako')), Rule('/share/atom/', 'get', search_views.search_share_atom, xml_renderer), Rule('/api/v1/user/search/', 'get', search_views.search_contributor, json_renderer), Rule( '/api/v1/search/node/', 'post', project_views.node.search_node, json_renderer, ), ]) # API process_rules(app, [ Rule(['/search/', '/search/<type>/'], ['get', 'post'], search_views.search_search, json_renderer), Rule('/search/projects/', 'get', search_views.search_projects_by_title, json_renderer), Rule('/share/search/', ['get', 'post'], search_views.search_share, json_renderer), Rule('/share/stats/', 'get', search_views.search_share_stats, json_renderer), Rule('/share/providers/', 'get', search_views.search_share_providers, json_renderer), ], prefix='/api/v1') # Project # Web process_rules( app, [ Rule('/', 'get', website_views.index, OsfWebRenderer('index.mako')), Rule('/goodbye/', 'get', goodbye, OsfWebRenderer('index.mako')), Rule([ '/project/<pid>/', '/project/<pid>/node/<nid>/', ], 'get', project_views.node.view_project, OsfWebRenderer('project/project.mako', trust=False)), # Create a new subproject/component Rule('/project/<pid>/newnode/', 'post', project_views.node.project_new_node, notemplate), # # TODO: Add API endpoint for tags # Rule('/tags/<tag>/', 'get', project_views.tag.project_tag, OsfWebRenderer('tags.mako')), Rule('/api/v1/folder/<nid>', 'post', project_views.node.folder_new_post, json_renderer), Rule('/project/new/<pid>/beforeTemplate/', 'get', project_views.node.project_before_template, json_renderer), Rule( [ '/project/<pid>/contributors/', '/project/<pid>/node/<nid>/contributors/', ], 'get', project_views.node.node_contributors, OsfWebRenderer('project/contributors.mako', trust=False), ), Rule([ '/project/<pid>/settings/', '/project/<pid>/node/<nid>/settings/', ], 'get', project_views.node.node_setting, OsfWebRenderer('project/settings.mako', trust=False)), # Permissions Rule( [ '/project/<pid>/permissions/<permissions>/', '/project/<pid>/node/<nid>/permissions/<permissions>/', ], 'post', project_views.node.project_set_privacy, OsfWebRenderer( 'project/project.mako' ) # TODO: Should this be notemplate? (post request) ), ### Logs ### # View forks Rule([ '/project/<pid>/forks/', '/project/<pid>/node/<nid>/forks/', ], 'get', project_views.node.node_forks, OsfWebRenderer('project/forks.mako', trust=False)), # Registrations Rule([ '/project/<pid>/register/', '/project/<pid>/node/<nid>/register/', ], 'get', project_views.register.node_register_page, OsfWebRenderer('project/register.mako', trust=False)), Rule([ '/project/<pid>/register/<template>/', '/project/<pid>/node/<nid>/register/<template>/', ], 'get', project_views.register.node_register_template_page, OsfWebRenderer('project/register.mako', trust=False)), Rule([ '/project/<pid>/registrations/', '/project/<pid>/node/<nid>/registrations/', ], 'get', project_views.node.node_registrations, OsfWebRenderer('project/registrations.mako', trust=False)), # TODO: Can't create a registration locally, so can't test this one..? Rule([ '/project/<pid>/retraction/', '/project/<pid>/node/<nid>/retraction/', ], 'get', project_views.register.node_registration_retraction_get, OsfWebRenderer('project/retract_registration.mako', trust=False)), Rule([ '/project/<pid>/retraction/approve/<token>/', '/project/<pid>/node/<nid>/retraction/approve/<token>/', ], 'get', project_views.register.node_registration_retraction_approve, OsfWebRenderer('error.mako', trust=False)), Rule( [ '/project/<pid>/retraction/disapprove/<token>/', '/project/<pid>/node/<nid>/retraction/disapprove/<token>/', ], 'get', project_views.register.node_registration_retraction_disapprove, OsfWebRenderer('error.mako', trust=False)), Rule([ '/project/<pid>/embargo/approve/<token>/', '/project/<pid>/node/<nid>/embargo/approve/<token>/', ], 'get', project_views.register.node_registration_embargo_approve, OsfWebRenderer('error.mako', trust=False)), Rule([ '/project/<pid>/embargo/disapprove/<token>/', '/project/<pid>/node/<nid>/embargo/disapprove/<token>/', ], 'get', project_views.register.node_registration_embargo_disapprove, OsfWebRenderer('error.mako', trust=False)), Rule( '/ids/<category>/<path:value>/', 'get', project_views.register.get_referent_by_identifier, notemplate, ), # Statistics Rule([ '/project/<pid>/statistics/', '/project/<pid>/node/<nid>/statistics/', ], 'get', project_views.node.project_statistics, OsfWebRenderer('project/statistics.mako', trust=False)), ### Files ### # Note: Web endpoint for files view must pass `mode` = `page` to # include project view data and JS includes # TODO: Start waterbutler to test Rule( [ '/project/<pid>/files/', '/project/<pid>/node/<nid>/files/', ], 'get', project_views.file.collect_file_trees, OsfWebRenderer('project/files.mako', trust=False), view_kwargs={'mode': 'page'}, ), Rule([ '/project/<pid>/files/<provider>/<path:path>/', '/project/<pid>/node/<nid>/files/<provider>/<path:path>/', ], 'get', addon_views.addon_view_or_download_file, OsfWebRenderer('project/view_file.mako', trust=False)), Rule( [ # Legacy Addon view file paths '/project/<pid>/<provider>/files/<path:path>/', '/project/<pid>/node/<nid>/<provider>/files/<path:path>/', '/project/<pid>/<provider>/files/<path:path>/download/', '/project/<pid>/node/<nid>/<provider>/files/<path:path>/download/', # Legacy routes for `download_file` '/project/<pid>/osffiles/<fid>/download/', '/project/<pid>/node/<nid>/osffiles/<fid>/download/', # Legacy routes for `view_file` '/project/<pid>/osffiles/<fid>/', '/project/<pid>/node/<nid>/osffiles/<fid>/', # Note: Added these old URLs for backwards compatibility with # hard-coded links. '/project/<pid>/osffiles/download/<fid>/', '/project/<pid>/node/<nid>/osffiles/download/<fid>/', '/project/<pid>/files/<fid>/', '/project/<pid>/node/<nid>/files/<fid>/', '/project/<pid>/files/download/<fid>/', '/project/<pid>/node/<nid>/files/download/<fid>/', # Legacy routes for `download_file_by_version` '/project/<pid>/osffiles/<fid>/version/<vid>/download/', '/project/<pid>/node/<nid>/osffiles/<fid>/version/<vid>/download/', # Note: Added these old URLs for backwards compatibility with # hard-coded links. '/project/<pid>/osffiles/<fid>/version/<vid>/', '/project/<pid>/node/<nid>/osffiles/<fid>/version/<vid>/', '/project/<pid>/osffiles/download/<fid>/version/<vid>/', '/project/<pid>/node/<nid>/osffiles/download/<fid>/version/<vid>/', '/project/<pid>/files/<fid>/version/<vid>/', '/project/<pid>/node/<nid>/files/<fid>/version/<vid>/', '/project/<pid>/files/download/<fid>/version/<vid>/', '/project/<pid>/node/<nid>/files/download/<fid>/version/<vid>/', ], 'get', addon_views.addon_view_or_download_file_legacy, OsfWebRenderer('project/view_file.mako', trust=False), ), Rule( [ # api/v1 Legacy routes for `download_file` '/api/v1/project/<pid>/osffiles/<fid>/', '/api/v1/project/<pid>/node/<nid>/osffiles/<fid>/', '/api/v1/project/<pid>/files/download/<fid>/', '/api/v1/project/<pid>/node/<nid>/files/download/<fid>/', #api/v1 Legacy routes for `download_file_by_version` '/api/v1/project/<pid>/osffiles/<fid>/version/<vid>/', '/api/v1/project/<pid>/node/<nid>/osffiles/<fid>/version/<vid>/', '/api/v1/project/<pid>/files/download/<fid>/version/<vid>/', '/api/v1/project/<pid>/node/<nid>/files/download/<fid>/version/<vid>/', ], 'get', addon_views.addon_view_or_download_file_legacy, json_renderer), ]) # API process_rules( app, [ Rule( '/email/meeting/', 'post', conference_views.meeting_hook, json_renderer, ), Rule('/mailchimp/hooks/', 'get', profile_views.mailchimp_get_endpoint, json_renderer), Rule('/mailchimp/hooks/', 'post', profile_views.sync_data_from_mailchimp, json_renderer), # Create project, used by projectCreator.js Rule('/project/new/', 'post', project_views.node.project_new_post, json_renderer), Rule([ '/project/<pid>/contributors_abbrev/', '/project/<pid>/node/<nid>/contributors_abbrev/', ], 'get', project_views.contributor.get_node_contributors_abbrev, json_renderer), Rule('/tags/<tag>/', 'get', project_views.tag.project_tag, json_renderer), Rule([ '/project/<pid>/', '/project/<pid>/node/<nid>/', ], 'get', project_views.node.view_project, json_renderer), Rule([ '/project/<pid>/expand/', '/project/<pid>/node/<nid>/expand/', ], 'post', project_views.node.expand, json_renderer), Rule([ '/project/<pid>/collapse/', '/project/<pid>/node/<nid>/collapse/', ], 'post', project_views.node.collapse, json_renderer), Rule( [ '/project/<pid>/pointer/', '/project/<pid>/node/<nid>/pointer/', ], 'get', project_views.node.get_pointed, json_renderer, ), Rule( [ '/project/<pid>/pointer/', '/project/<pid>/node/<nid>/pointer/', ], 'post', project_views.node.add_pointers, json_renderer, ), Rule( [ '/pointer/', ], 'post', project_views.node.add_pointer, json_renderer, ), Rule( [ '/pointers/move/', ], 'post', project_views.node.move_pointers, json_renderer, ), Rule( [ '/project/<pid>/pointer/', '/project/<pid>/node/<nid>pointer/', ], 'delete', project_views.node.remove_pointer, json_renderer, ), Rule( [ '/folder/<pid>/pointer/<pointer_id>', ], 'delete', project_views.node.remove_pointer_from_folder, json_renderer, ), Rule( [ '/folder/<pid>/pointers/', ], 'delete', project_views.node.remove_pointers_from_folder, json_renderer, ), Rule( [ '/folder/<pid>', ], 'delete', project_views.node.delete_folder, json_renderer, ), Rule('/folder/', 'put', project_views.node.add_folder, json_renderer), Rule([ '/project/<pid>/get_summary/', '/project/<pid>/node/<nid>/get_summary/', ], 'get', project_views.node.get_summary, json_renderer), Rule([ '/project/<pid>/get_children/', '/project/<pid>/node/<nid>/get_children/', ], 'get', project_views.node.get_children, json_renderer), Rule(['/project/<pid>/get_folder_pointers/'], 'get', project_views.node.get_folder_pointers, json_renderer), Rule([ '/project/<pid>/get_forks/', '/project/<pid>/node/<nid>/get_forks/', ], 'get', project_views.node.get_forks, json_renderer), Rule([ '/project/<pid>/get_registrations/', '/project/<pid>/node/<nid>/get_registrations/', ], 'get', project_views.node.get_registrations, json_renderer), Rule('/log/<log_id>/', 'get', project_views.log.get_log, json_renderer), Rule([ '/project/<pid>/log/', '/project/<pid>/node/<nid>/log/', ], 'get', project_views.log.get_logs, json_renderer), Rule([ '/project/<pid>/get_contributors/', '/project/<pid>/node/<nid>/get_contributors/', ], 'get', project_views.contributor.get_contributors, json_renderer), Rule([ '/project/<pid>/get_contributors_from_parent/', '/project/<pid>/node/<nid>/get_contributors_from_parent/', ], 'get', project_views.contributor.get_contributors_from_parent, json_renderer), # Reorder contributors Rule( [ '/project/<pid>/contributors/manage/', '/project/<pid>/node/<nid>/contributors/manage/', ], 'POST', project_views.contributor.project_manage_contributors, json_renderer, ), Rule([ '/project/<pid>/get_most_in_common_contributors/', '/project/<pid>/node/<nid>/get_most_in_common_contributors/', ], 'get', project_views.contributor.get_most_in_common_contributors, json_renderer), Rule([ '/project/<pid>/get_recently_added_contributors/', '/project/<pid>/node/<nid>/get_recently_added_contributors/', ], 'get', project_views.contributor.get_recently_added_contributors, json_renderer), Rule([ '/project/<pid>/get_editable_children/', '/project/<pid>/node/<nid>/get_editable_children/', ], 'get', project_views.node.get_editable_children, json_renderer), # Private Link Rule([ '/project/<pid>/private_link/', '/project/<pid>/node/<nid>/private_link/', ], 'post', project_views.node.project_generate_private_link_post, json_renderer), Rule([ '/project/<pid>/private_link/edit/', '/project/<pid>/node/<nid>/private_link/edit/', ], 'put', project_views.node.project_private_link_edit, json_renderer), Rule([ '/project/<pid>/private_link/', '/project/<pid>/node/<nid>/private_link/', ], 'delete', project_views.node.remove_private_link, json_renderer), Rule([ '/project/<pid>/private_link/', '/project/<pid>/node/<nid>/private_link/', ], 'get', project_views.node.private_link_table, json_renderer), # Create, using existing project as a template Rule([ '/project/new/<nid>/', ], 'post', project_views.node.project_new_from_template, json_renderer), # Update Rule( [ '/project/<pid>/', '/project/<pid>/node/<nid>/', ], 'put', project_views.node.update_node, json_renderer, ), # Remove Rule( [ '/project/<pid>/', '/project/<pid>/node/<nid>/', ], 'delete', project_views.node.component_remove, json_renderer, ), # Reorder components Rule('/project/<pid>/reorder_components/', 'post', project_views.node.project_reorder_components, json_renderer), # Edit node Rule([ '/project/<pid>/edit/', '/project/<pid>/node/<nid>/edit/', ], 'post', project_views.node.edit_node, json_renderer), # Add / remove tags Rule([ '/project/<pid>/tags/', '/project/<pid>/node/<nid>/tags/', '/project/<pid>/tags/<tag>/', '/project/<pid>/node/<nid>/tags/<tag>/', ], 'post', project_views.tag.project_add_tag, json_renderer), Rule([ '/project/<pid>/tags/', '/project/<pid>/node/<nid>/tags/', '/project/<pid>/tags/<tag>/', '/project/<pid>/node/<nid>/tags/<tag>/', ], 'delete', project_views.tag.project_remove_tag, json_renderer), # Add / remove contributors Rule([ '/project/<pid>/contributors/', '/project/<pid>/node/<nid>/contributors/', ], 'post', project_views.contributor.project_contributors_post, json_renderer), Rule([ '/project/<pid>/beforeremovecontributors/', '/project/<pid>/node/<nid>/beforeremovecontributors/', ], 'post', project_views.contributor.project_before_remove_contributor, json_renderer), # TODO(sloria): should be a delete request to /contributors/ Rule([ '/project/<pid>/removecontributors/', '/project/<pid>/node/<nid>/removecontributors/', ], 'post', project_views.contributor.project_removecontributor, json_renderer), # Forks Rule( [ '/project/<pid>/fork/before/', '/project/<pid>/node/<nid>/fork/before/', ], 'get', project_views.node.project_before_fork, json_renderer, ), Rule( [ '/project/<pid>/fork/', '/project/<pid>/node/<nid>/fork/', ], 'post', project_views.node.node_fork_page, json_renderer, ), Rule( [ '/project/<pid>/pointer/fork/', '/project/<pid>/node/<nid>/pointer/fork/', ], 'post', project_views.node.fork_pointer, json_renderer, ), # View forks Rule([ '/project/<pid>/forks/', '/project/<pid>/node/<nid>/forks/', ], 'get', project_views.node.node_forks, json_renderer), # Registrations Rule([ '/project/<pid>/beforeregister/', '/project/<pid>/node/<nid>/beforeregister', ], 'get', project_views.register.project_before_register, json_renderer), Rule([ '/project/<pid>/register/<template>/', '/project/<pid>/node/<nid>/register/<template>/', ], 'get', project_views.register.node_register_template_page, json_renderer), Rule([ '/project/<pid>/retraction/', '/project/<pid>/node/<nid>/retraction/' ], 'post', project_views.register.node_registration_retraction_post, json_renderer), Rule([ '/project/<pid>/register/<template>/', '/project/<pid>/node/<nid>/register/<template>/', ], 'post', project_views.register.node_register_template_page_post, json_renderer), Rule( [ '/project/<pid>/identifiers/', '/project/<pid>/node/<nid>/identifiers/', ], 'get', project_views.register.node_identifiers_get, json_renderer, ), Rule( [ '/project/<pid>/identifiers/', '/project/<pid>/node/<nid>/identifiers/', ], 'post', project_views.register.node_identifiers_post, json_renderer, ), # Statistics Rule([ '/project/<pid>/statistics/', '/project/<pid>/node/<nid>/statistics/', ], 'get', project_views.node.project_statistics, json_renderer), # Permissions Rule([ '/project/<pid>/permissions/<permissions>/', '/project/<pid>/node/<nid>/permissions/<permissions>/', ], 'post', project_views.node.project_set_privacy, json_renderer), Rule([ '/project/<pid>/permissions/beforepublic/', '/project/<pid>/node/<nid>/permissions/beforepublic/', ], 'get', project_views.node.project_before_set_public, json_renderer), ### Wiki ### ### Watching ### Rule(['/project/<pid>/watch/', '/project/<pid>/node/<nid>/watch/'], 'post', project_views.node.watch_post, json_renderer), Rule([ '/project/<pid>/unwatch/', '/project/<pid>/node/<nid>/unwatch/' ], 'post', project_views.node.unwatch_post, json_renderer), Rule([ '/project/<pid>/togglewatch/', '/project/<pid>/node/<nid>/togglewatch/' ], 'post', project_views.node.togglewatch_post, json_renderer), Rule(['/watched/logs/'], 'get', website_views.watched_logs_get, json_renderer), ### Accounts ### Rule(['/user/merge/'], 'post', auth_views.merge_user_post, json_renderer), # Combined files Rule( ['/project/<pid>/files/', '/project/<pid>/node/<nid>/files/'], 'get', project_views.file.collect_file_trees, json_renderer, ), # Endpoint to fetch Rubeus.JS/Hgrid-formatted data Rule([ '/project/<pid>/files/grid/', '/project/<pid>/node/<nid>/files/grid/' ], 'get', project_views.file.grid_data, json_renderer), # Settings Rule( '/files/auth/', 'get', addon_views.get_auth, json_renderer, ), Rule( [ '/project/<pid>/waterbutler/logs/', '/project/<pid>/node/<nid>/waterbutler/logs/', ], 'put', addon_views.create_waterbutler_log, json_renderer, ), Rule( [ '/registration/<pid>/callbacks/', ], 'put', project_views.register.registration_callbacks, json_renderer, ), Rule( '/settings/addons/', 'post', profile_views.user_choose_addons, json_renderer, ), Rule( '/settings/notifications/', 'get', profile_views.user_notifications, json_renderer, ), Rule( '/settings/notifications/', 'post', profile_views.user_choose_mailing_lists, json_renderer, ), Rule( '/subscriptions/', 'get', notification_views.get_subscriptions, json_renderer, ), Rule( [ '/project/<pid>/subscriptions/', '/project/<pid>/node/<nid>/subscriptions/' ], 'get', notification_views.get_node_subscriptions, json_renderer, ), Rule( '/subscriptions/', 'post', notification_views.configure_subscription, json_renderer, ), Rule( [ '/project/<pid>/settings/addons/', '/project/<pid>/node/<nid>/settings/addons/', ], 'post', project_views.node.node_choose_addons, json_renderer, ), Rule( [ '/project/<pid>/settings/comments/', '/project/<pid>/node/<nid>/settings/comments/', ], 'post', project_views.node.configure_comments, json_renderer, ), # Invite Users Rule([ '/project/<pid>/invite_contributor/', '/project/<pid>/node/<nid>/invite_contributor/' ], 'post', project_views.contributor.invite_contributor_post, json_renderer), ], prefix='/api/v1') # Set up static routing for addons # NOTE: We use nginx to serve static addon assets in production addon_base_path = os.path.abspath('website/addons') if settings.DEV_MODE: @app.route('/static/addons/<addon>/<path:filename>') def addon_static(addon, filename): addon_path = os.path.join(addon_base_path, addon, 'static') return send_from_directory(addon_path, filename)
from framework.routing import Rule, json_renderer from addons.azureblobstorage import views api_routes = { 'rules': [ Rule( [ '/settings/azureblobstorage/accounts/', ], 'post', views.azureblobstorage_add_user_account, json_renderer, ), Rule( [ '/settings/azureblobstorage/accounts/', ], 'get', views.azureblobstorage_account_list, json_renderer, ), Rule( [ '/project/<pid>/azureblobstorage/settings/', '/project/<pid>/node/<nid>/azureblobstorage/settings/', ], 'put', views.azureblobstorage_set_config, json_renderer,
def test_error_handling(self): rule = Rule(['/error/'], 'get', error_view, renderer=json_renderer) process_rules(self.app, [rule]) res = self.wt.get('/error/', expect_errors=True) assert_equal(res.status_code, 400) assert_true(isinstance(res.json, dict))
# -*- coding: utf-8 -*- """Dropbox addon routes.""" from framework.routing import Rule, json_renderer from addons.dropbox import views auth_routes = { 'rules': [ Rule( '/settings/dropbox/accounts/', 'get', views.dropbox_account_list, json_renderer, ) ], 'prefix': '/api/v1' } api_routes = { 'rules': [ ##### Node settings ##### Rule([ '/project/<pid>/dropbox/config/', '/project/<pid>/node/<nid>/dropbox/config/' ], 'get', views.dropbox_get_config, json_renderer), Rule([ '/project/<pid>/dropbox/config/', '/project/<pid>/node/<nid>/dropbox/config/' ], 'put', views.dropbox_set_config, json_renderer),
# -*- coding: utf-8 -*- from framework.routing import Rule, json_renderer from addons.gitlab import views api_routes = { 'rules': [ Rule( '/settings/gitlab/', 'get', views.gitlab_user_config_get, json_renderer, ), Rule( '/settings/gitlab/accounts/', 'post', views.gitlab_add_user_account, json_renderer, ), Rule( [ '/settings/gitlab/accounts/', ], 'get', views.gitlab_account_list, json_renderer, ), Rule( [ '/project/<pid>/gitlab/settings/',
from framework.routing import Rule, json_renderer from website.routes import OsfWebRenderer, notemplate from website.addons.osfstorage import views web_routes = { 'rules': [ Rule( [ '/project/<pid>/osfstorage/files/<path:path>/', '/project/<pid>/node/<nid>/osfstorage/files/<path:path>/', ], 'get', views.osf_storage_view_file, OsfWebRenderer('../addons/osfstorage/templates/osfstorage_view_file.mako'), ), Rule( [ # Legacy routes for `view_file` '/project/<pid>/osffiles/<fid>/', '/project/<pid>/node/<nid>/osffiles/<fid>/', ], 'get', views.osf_storage_view_file_legacy, OsfWebRenderer('../addons/osfstorage/templates/osfstorage_view_file.mako'), ),
# -*- coding: utf-8 -*- from framework.routing import Rule, json_renderer from website.addons.mendeley import views api_routes = { 'rules': [ Rule( [ '/settings/mendeley/accounts/', ], 'get', views.mendeley_get_user_accounts, json_renderer, ), Rule( [ '/project/<pid>/mendeley/settings/', '/project/<pid>/node/<nid>/mendeley/settings/', ], 'get', views.mendeley_get_config, json_renderer, ), Rule( [ '/project/<pid>/mendeley/settings/', '/project/<pid>/node/<nid>/mendeley/settings/', ], 'put',
""" """ from framework.routing import Rule, json_renderer from website.routes import OsfWebRenderer from . import views settings_routes = { 'rules': [ Rule( '/settings/dataverse/', 'get', views.auth.dataverse_user_config_get, json_renderer, ), Rule( '/settings/dataverse/accounts/', 'post', views.config.dataverse_add_user_account, json_renderer, ), Rule( '/settings/dataverse/accounts/', 'get', views.config.dataverse_get_user_accounts, json_renderer, ), ], 'prefix':
from framework.routing import Rule, json_renderer from website.routes import OsfWebRenderer from . import views TEMPLATE_DIR = '../addons/wiki/templates/' settings_routes = { 'rules': [], 'prefix': '/api/v1', } widget_routes = { 'rules': [ Rule([ '/project/<pid>/wiki/widget/', '/project/<pid>/node/<nid>/wiki/widget/', ], 'get', views.wiki_widget, json_renderer), ], 'prefix': '/api/v1', } # NOTE: <wname> refers to a wiki page's key, e.g. 'Home' page_routes = { 'rules': [ # Home (Base) | GET Rule([ '/project/<pid>/wiki/', '/project/<pid>/node/<nid>/wiki/', ], 'get', views.project_wiki_home,
from framework.routing import Rule, json_renderer from . import views settings_routes = { 'rules': [ # Settings Rule([ '/settings/twofactor/', ], 'put', views.twofactor_settings_put, json_renderer), Rule([ '/settings/twofactor/', ], 'get', views.twofactor_settings_get, json_renderer), # Enable Two-factor Rule([ '/settings/twofactor/', ], 'post', views.twofactor_enable, json_renderer), # Disable Two-factor Rule([ '/settings/twofactor/', ], 'delete', views.twofactor_disable, json_renderer), ], 'prefix': '/api/v1' }
# -*- coding: utf-8 -*- """Forward addon routes.""" from framework.routing import Rule, json_renderer from addons.forward import views api_routes = { 'rules': [ Rule( [ '/project/<pid>/forward/config/', '/project/<pid>/node/<nid>/forward/config/' ], 'get', views.config.forward_config_get, json_renderer, ), Rule( [ '/project/<pid>/forward/config/', '/project/<pid>/node/<nid>/forward/config/' ], 'put', views.config.forward_config_put, json_renderer, ), ], 'prefix': '/api/v1', }
# -*- coding: utf-8 -*- from framework.routing import Rule, json_renderer from addons.zotero.views import zotero_views api_routes = { 'rules': [ Rule( [ '/settings/zotero/accounts/', ], 'get', zotero_views.account_list(), json_renderer, ), Rule( [ '/project/<pid>/zotero/settings/', '/project/<pid>/node/<nid>/zotero/settings/', ], 'get', zotero_views.get_config(), json_renderer, ), Rule( [ '/project/<pid>/zotero/settings/', '/project/<pid>/node/<nid>/zotero/settings/', ], 'put',
# -*- coding: utf-8 -*- """Dropbox addon routes.""" from framework.routing import Rule, json_renderer from website.addons.dropbox import views auth_routes = { 'rules': [ Rule( '/settings/dropbox/', 'get', views.auth.dropbox_user_config_get, json_renderer, ), ##### OAuth ##### Rule( '/settings/dropbox/oauth/', 'get', views.auth. dropbox_oauth_start, # Use same view func as node oauth start json_renderer, endpoint_suffix='_user' # but add a suffix for url_for ), Rule( '/addons/dropbox/oauth/finish/', 'get', views.auth.dropbox_oauth_finish, json_renderer, ), Rule(
# -*- coding: utf-8 -*- from framework.routing import Rule, json_renderer from website.addons.figshare import views api_routes = { 'rules': [ Rule( [ '/settings/figshare/accounts/', ], 'get', views.figshare_account_list, json_renderer, ), Rule( [ '/project/<pid>/figshare/settings/', '/project/<pid>/node/<nid>/figshare/settings/' ], 'get', views.figshare_get_config, json_renderer, ), Rule( [ '/project/<pid>/figshare/settings/', '/project/<pid>/node/<nid>/figshare/settings/' ], 'put', views.figshare_set_config,
# -*- coding: utf-8 -*- from framework.routing import Rule, json_renderer from addons.owncloud import views # JSON endpoints api_routes = { 'rules': [ Rule( [ '/project/<pid>/owncloud/user-auth/', '/project/<pid>/node/<nid>/owncloud/user-auth/', ], 'delete', views.owncloud_deauthorize_node, json_renderer, ), Rule( '/settings/owncloud/accounts/', 'get', views.owncloud_account_list, json_renderer, ), Rule([ '/project/<pid>/owncloud/settings/', '/project/<pid>/node/<nid>/owncloud/settings/' ], 'put', views.owncloud_set_config, json_renderer), Rule([ '/project/<pid>/owncloud/settings/', '/project/<pid>/node/<nid>/owncloud/settings/' ], 'get', views.owncloud_get_config, json_renderer),
# -*- coding: utf-8 -*- """Forward addon routes.""" from framework.routing import Rule, json_renderer from website.routes import OsfWebRenderer from website.addons.forward import views api_routes = { 'rules': [ Rule( [ '/project/<pid>/forward/config/', '/project/<pid>/node/<nid>/forward/config/' ], 'get', views.config.forward_config_get, json_renderer, ), Rule( [ '/project/<pid>/forward/config/', '/project/<pid>/node/<nid>/forward/config/' ], 'put', views.config.forward_config_put, json_renderer, ), Rule( [ '/project/<pid>/forward/widget/', '/project/<pid>/node/<nid>/forward/widget/',
# -*- coding: utf-8 -*- """OneDrive addon routes.""" from framework.routing import Rule, json_renderer from addons.onedrive import views api_routes = { 'rules': [ #### Profile settings ### Rule( [ '/settings/onedrive/accounts/', ], 'get', views.onedrive_account_list, json_renderer, ), ##### Node settings ##### Rule( [ '/project/<pid>/onedrive/folders/', '/project/<pid>/node/<nid>/onedrive/folders/', ], 'get', views.onedrive_folder_list, json_renderer, ), Rule( [ '/project/<pid>/onedrive/config/', '/project/<pid>/node/<nid>/onedrive/config/'