def _dispatch(event_rh, category_rh): event_view = make_view_func(event_rh) categ_view = make_view_func(category_rh) def view_func(**kwargs): return categ_view(**kwargs) if kwargs['object_type'] == 'category' else event_view(**kwargs) return view_func
def test_get_request_user_nested_exceptions(mocker, app, test_client): process_called = False class RHFail(RH): def _process(self): nonlocal process_called process_called = True raise Exception('badaboom') app.add_url_rule('/test/fail', 'test_fail', make_view_func(RHFail)) # page does not exist resp = test_client.get('/test/this-does-not-exist?user_token=garbage') assert resp.status_code == 404 assert b'Not Found' in resp.data # existing page but invalid token, just making sure we never get into processing that resp = test_client.get('/test/fail?user_token=garbage') assert resp.status_code == 400 assert b'The persistent link you used is invalid' in resp.data # random failure during authentication on an existing page mocker.patch('indico.web.util._lookup_request_user', side_effect=Exception('kaboom')) resp = test_client.get('/test/fail?user_token=garbage') assert resp.status_code == 500 assert b'kaboom' in resp.data # random failure during authentication on 404ing page resp = test_client.get('/test/this-does-not-exist?user_token=garbage') assert resp.status_code == 404 assert b'Not Found' in resp.data # none of the requests should have ended up in the RH assert not process_called
def add_url_rule(self, rule, endpoint=None, view_func=None, **options): if view_func is not None: # We might have a RH class here - convert it to a callable suitable as a view func. view_func = make_view_func(view_func) super(IndicoBlueprint, self).add_url_rule(self.__default_prefix + rule, endpoint, view_func, **options) if self.__prefix: super(IndicoBlueprint, self).add_url_rule(self.__prefix + rule, endpoint, view_func, **options)
def test_token_access_mixin(dummy_event, app, test_client): class RHTest(TokenAccessMixin, RH): def _process(self): return f'{self._token_can_access()}|{self.is_service_call}'.lower() class RHTestServiceAllowed(TokenAccessMixin, RH): SERVICE_ALLOWED = True def can_access(self): # must be called here for CSRF self._token_can_access() def _process(self): return f'{self._token_can_access()}|{self.is_service_call}'.lower() app.add_url_rule('/test/<int:event_id>/no-service', 'test_no_service', make_view_func(RHTest)) app.add_url_rule('/test/<int:event_id>/service', 'test_service', make_view_func(RHTestServiceAllowed), methods=('GET', 'POST')) token = f'{TOKEN_PREFIX_SERVICE}{uuid4()}' editing_settings.set(dummy_event, 'service_token', token) # no auth assert test_client.get( f'/test/{dummy_event.id}/no-service').data == b'false|false' assert test_client.get( f'/test/{dummy_event.id}/service').data == b'false|false' # service token service_auth = {'headers': {'Authorization': f'Bearer {token}'}} assert test_client.get(f'/test/{dummy_event.id}/no-service', **service_auth).data == b'false|false' assert test_client.get(f'/test/{dummy_event.id}/service', **service_auth).data == b'true|true' # csrf resp = test_client.post(f'/test/{dummy_event.id}/service') assert resp.status_code == 400 assert b'problem with your current session' in resp.data assert test_client.post(f'/test/{dummy_event.id}/service', **service_auth).data == b'true|true'
def test_get_request_user_oauth_querystring(db, dummy_user, app, test_client): # TODO: remove this once indico-checkin no longer sends tokens in the query string! from indico.core.oauth.models.applications import OAuthApplication, OAuthApplicationUserLink, SystemAppType from indico.core.oauth.models.tokens import OAuthToken @oauth_scope('registrants') class RHTest(RH): def _process(self): user, source = get_request_user() assert session.user == user if not user: return 'none' return f'{user.id}|{source}' app.add_url_rule('/test/registrants', 'test_registrants', make_view_func(RHTest), methods=('GET', 'POST')) checkin_app = OAuthApplication.query.filter_by( system_app_type=SystemAppType.checkin).one() app_link = OAuthApplicationUserLink(application=checkin_app, user=dummy_user, scopes=['registrants']) token_string = 'x' * 40 OAuthToken(access_token=token_string, app_user_link=app_link, scopes=['registrants']) db.session.flush() resp = test_client.get('/test/registrants', headers={'Authorization': f'Bearer {token_string}'}) assert resp.status_code == 200 assert resp.data == b'1337|oauth' resp = test_client.post( '/test/registrants', headers={'Authorization': f'Bearer {token_string}'}) assert resp.status_code == 200 assert resp.data == b'1337|oauth' resp = test_client.get(f'/test/registrants?access_token={token_string}') assert resp.status_code == 200 assert resp.data == b'1337|oauth' resp = test_client.post(f'/test/registrants?access_token={token_string}') assert resp.status_code == 200 assert resp.data == b'1337|oauth'
def _before_request(self): if request.endpoint == 'categories.display': return redirect(url_for('rb.roombooking')) elif request.endpoint == 'rb.roombooking': # render our own landing page instead of the original RH return make_view_func(RHLanding)()
def test_get_request_user_complete(dummy_user, app, test_client, dummy_token, create_user): class RHTest(RH): def _process(self): user, source = get_request_user() assert session.user == user if not user: return 'none' return f'{user.id}|{source}' @allow_signed_url class RHTestSigned(RHTest): pass @oauth_scope('read:user') class RHTestScope(RHTest): pass app.add_url_rule('/test/default', 'test_default', make_view_func(RHTest), methods=('GET', 'POST')) app.add_url_rule('/test/signed', 'test_signed', make_view_func(RHTestSigned)) app.add_url_rule('/test/scope', 'test_scope', make_view_func(RHTestScope), methods=('GET', 'POST')) # no auth assert test_client.get('/test/default').data == b'none' assert test_client.get('/test/signed').data == b'none' assert test_client.get('/test/scope').data == b'none' # signature auth resp = test_client.get(signed_url_for_user(dummy_user, 'test_default')) assert resp.status_code == 400 assert b'Signature auth is not allowed for this URL' in resp.data resp = test_client.get(signed_url_for_user(dummy_user, 'test_signed')) assert resp.status_code == 200 assert resp.data == b'1337|signed_url' resp = test_client.get(signed_url_for_user(dummy_user, 'test_scope')) assert resp.status_code == 400 assert b'Signature auth is not allowed for this URL' in resp.data # oauth - token with read:user scope oauth_headers = {'Authorization': f'Bearer {dummy_token._plaintext_token}'} resp = test_client.get('/test/default', headers=oauth_headers) assert resp.status_code == 403 assert b'insufficient_scope' in resp.data resp = test_client.post('/test/default', headers=oauth_headers) assert resp.status_code == 403 assert b'insufficient_scope' in resp.data resp = test_client.get('/test/signed', headers=oauth_headers) assert resp.status_code == 403 assert b'insufficient_scope' in resp.data resp = test_client.get('/test/scope', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' resp = test_client.post('/test/scope', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' # oauth - token with read:everything scope dummy_token._scopes.append('read:everything') dummy_token.app_user_link.scopes.append('read:everything') dummy_token.app_user_link.application.allowed_scopes.append('read:everything') resp = test_client.get('/test/default', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' # default post requires full:everything resp = test_client.post('/test/default', headers=oauth_headers) assert resp.status_code == 403 assert b'insufficient_scope' in resp.data resp = test_client.get('/test/signed', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' resp = test_client.get('/test/scope', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' # custom scopes are not method-specific resp = test_client.post('/test/scope', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' # full:everything should allow posting to any endpoint dummy_token._scopes.append('full:everything') dummy_token.app_user_link.scopes.append('full:everything') dummy_token.app_user_link.application.allowed_scopes.append('full:everything') resp = test_client.post('/test/default', headers=oauth_headers) assert resp.status_code == 200 assert resp.data == b'1337|oauth' # oauth + signature is not allowed resp = test_client.get(signed_url_for_user(dummy_user, 'test_signed'), headers=oauth_headers) assert resp.status_code == 400 assert b'OAuth tokens and signed URLs cannot be mixed' in resp.data # request with a user being set in the actual session (session cookies in the browser) with test_client.session_transaction() as sess: sess.set_session_user(create_user(123)) assert test_client.get('/test/default').data == b'123|session' assert test_client.get('/test/signed').data == b'123|session' assert test_client.get('/test/scope').data == b'123|session' # oauth + session is not allowed resp = test_client.get('/test/default', headers=oauth_headers) assert resp.status_code == 400 assert b'OAuth tokens and session cookies cannot be mixed' in resp.data # regular requests still need a CSRF token resp = test_client.post('/test/default') assert resp.status_code == 400 assert b'problem with your current session' in resp.data # signed links override the session user resp = test_client.get(signed_url_for_user(dummy_user, 'test_signed')) assert resp.status_code == 200 assert resp.data == b'1337|signed_url'