def get_or_create_cookie(self, secret=None): """Find the cookie for the given user Create a new session if no cookie is found :param str secret: The key to sign the cookie with :returns: The signed cookie """ secret = secret or settings.SECRET_KEY sessions = Session.find( Q('data.auth_user_id', 'eq', self._id) ).sort( '-date_modified' ).limit(1) if sessions.count() > 0: user_session = sessions[0] else: user_session = Session(data={ 'auth_user_id': self._id, 'auth_user_username': self.username, 'auth_user_fullname': self.fullname, }) user_session.save() signer = itsdangerous.Signer(secret) return signer.sign(user_session._id)
def test_cookie_has_admin(self): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) res = self.app.get(self.url) assert_equal(res.status_code, 200) assert_equal(res.json['meta']['admin'], True)
def test_cookied_requests_can_create_and_email(self, mock_mail): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) assert_equal( User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 0) res = self.app.post_json_api( '{}?send_email=true'.format(self.base_url), self.data) assert_equal(res.status_code, 201) assert_equal( User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 1) assert_equal(mock_mail.call_count, 1)
def test_cookied_requests_can_create_and_email(self, mock_mail): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) assert_equal(User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 0) res = self.app.post_json_api( '{}?send_email=true'.format(self.base_url), self.data ) assert_equal(res.status_code, 201) assert_equal(User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 1) assert_equal(mock_mail.call_count, 1)
def test_cookied_requests_do_not_create_or_email(self, mock_mail): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) assert_equal(User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 0) res = self.app.post_json_api( self.base_url, self.data, expect_errors=True ) assert_equal(res.status_code, 403) assert_equal(User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 0) assert_equal(mock_mail.call_count, 0)
def test_file_guid_created_with_cookie(self, mock_allow): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(website_settings.SECRET_KEY).sign(session._id) self.app.set_cookie(website_settings.COOKIE_NAME, str(cookie)) res = self.app.get(self.file_url + '?create_guid=1', auth=self.user.auth) self.app.reset() # clear cookie assert_equal(res.status_code, 200) guid = res.json['data']['attributes'].get('guid', None) assert_is_not_none(guid) assert_equal(guid, self.file.get_guid()._id) assert_equal(mock_allow.call_count, 1)
def test_file_guid_created_with_cookie(self, mock_allow): session = Session(data={"auth_user_id": self.user._id}) session.save() cookie = itsdangerous.Signer(website_settings.SECRET_KEY).sign(session._id) self.app.set_cookie(website_settings.COOKIE_NAME, str(cookie)) res = self.app.get(self.file_url + "?create_guid=1", auth=self.user.auth) self.app.reset() # clear cookie assert_equal(res.status_code, 200) guid = res.json["data"]["attributes"].get("guid", None) assert_is_not_none(guid) assert_equal(guid, self.file.get_guid()._id) assert_equal(mock_allow.call_count, 1)
def create_session(response, data=None): current_session = get_session() if current_session: current_session.data.update(data or {}) current_session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign( current_session._id) else: session_id = str(bson.objectid.ObjectId()) new_session = Session(_id=session_id, data=data or {}) new_session.save() cookie_value = itsdangerous.Signer( settings.SECRET_KEY).sign(session_id) set_session(new_session) if response is not None: response.set_cookie(settings.COOKIE_NAME, value=cookie_value, domain=settings.OSF_COOKIE_DOMAIN, secure=settings.SESSION_COOKIE_SECURE, httponly=settings.SESSION_COOKIE_HTTPONLY) return response
def create_session(response, data=None): current_session = get_session() if current_session: current_session.data.update(data or {}) current_session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign(current_session._id) else: session_id = str(bson.objectid.ObjectId()) new_session = Session(_id=session_id, data=data or {}) new_session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign(session_id) set_session(new_session) if response is not None: response.set_cookie( settings.COOKIE_NAME, value=cookie_value, domain=settings.OSF_COOKIE_DOMAIN, secure=settings.SESSION_COOKIE_SECURE, httponly=settings.SESSION_COOKIE_HTTPONLY, ) return response
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1') self.test_app = webtest.TestApp(self.flask_app) self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = AddonGitHubOauthSettings(github_user_id='john') self.oauth_settings.save() self.user_addon.oauth_settings = self.oauth_settings self.user_addon.oauth_access_token = 'secret' self.user_addon.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.save() def build_url(self, **kwargs): options = dict( action='download', cookie=self.cookie, nid=self.node._id, provider=self.node_addon.config.short_name, ) options.update(kwargs) return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.test_app.get(url) assert_equal(res.json['auth'], views.make_auth(self.user)) assert_equal(res.json['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(res.json['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(res.json['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.test_app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.test_app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.test_app.get(url, expect_errors=True) assert_equal(res.status_code, 400) def test_auth_bad_ip(self): flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='192.168.1.1') test_app = webtest.TestApp(flask_app) url = self.build_url() res = test_app.get(url, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = AddonGitHubOauthSettings(github_user_id='john') self.oauth_settings.save() self.user_addon.oauth_settings = self.oauth_settings self.user_addon.oauth_access_token = 'secret' self.user_addon.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(self.node.logs) self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, "perform not called") def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'old.txt', 'kind': 'file', }, ) self.app.put_json( url, payload, headers={'Content-Type': 'application/json'} ) self.node.reload() assert_equal( self.node.logs[-1].action, 'github_addon_file_renamed', )
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1') self.test_app = webtest.TestApp(self.flask_app) self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = AddonGitHubOauthSettings(github_user_id='john') self.oauth_settings.save() self.user_addon.oauth_settings = self.oauth_settings self.user_addon.oauth_access_token = 'secret' self.user_addon.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } def test_add_log(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(self.node.logs) self.test_app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = len(self.node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = len(self.node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = len(self.node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs)
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1') self.test_app = webtest.TestApp(self.flask_app) self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = AddonGitHubOauthSettings(github_user_id='john') self.oauth_settings.save() self.user_addon.oauth_settings = self.oauth_settings self.user_addon.oauth_access_token = 'secret' self.user_addon.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.save() def build_url(self, **kwargs): options = dict( action='download', cookie=self.cookie, nid=self.node._id, provider=self.node_addon.config.short_name, ) options.update(kwargs) return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.test_app.get(url) assert_equal(res.json['auth'], views.make_auth(self.user)) assert_equal(res.json['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(res.json['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(res.json['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.test_app.get(url, expect_errors=True) assert_equal(res.status_code, 400) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.test_app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.test_app.get(url, expect_errors=True) assert_equal(res.status_code, 400) def test_auth_bad_ip(self): flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='192.168.1.1') test_app = webtest.TestApp(flask_app) url = self.build_url() res = test_app.get(url, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1') self.test_app = webtest.TestApp(self.flask_app) self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign( self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = AddonGitHubOauthSettings(github_user_id='john') self.oauth_settings.save() self.user_addon.oauth_settings = self.oauth_settings self.user_addon.oauth_access_token = 'secret' self.user_addon.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(self.node.logs) self.test_app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, "perform not called") def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = len(self.node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = len(self.node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = len(self.node.logs) res = self.test_app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': { '_id': self.node._id }, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': { '_id': self.node._id }, 'name': 'old.txt', 'kind': 'file', }, ) self.test_app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal( self.node.logs[-1].action, 'github_addon_file_renamed', )
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={"auth_user_id": self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf( settings.WATERBUTLER_JWE_SECRET.encode("utf-8"), settings.WATERBUTLER_JWE_SALT.encode("utf-8") ) def configure_addon(self): self.user.add_addon("github") self.user_addon = self.user.get_addon("github") self.oauth_settings = GitHubAccountFactory(display_name="john") self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon("github", self.auth_obj) self.node_addon = self.node.get_addon("github") self.node_addon.user = "******" self.node_addon.repo = "youre-my-best-friend" self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_url(self, **kwargs): options = { "payload": jwe.encrypt( jwt.encode( { "data": dict( dict(action="download", nid=self.node._id, provider=self.node_addon.config.short_name), **kwargs ), "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION), }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM, ), self.JWE_KEY, ) } return api_url_for("get_auth", **options) def test_auth_download(self): url = self.build_url() res = self.app.get(url, auth=self.user.auth) data = jwt.decode( jwe.decrypt(res.json["payload"].encode("utf-8"), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM, )["data"] assert_equal(data["auth"], views.make_auth(self.user)) assert_equal(data["credentials"], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data["settings"], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for("create_waterbutler_log", _absolute=True)) observed_url = furl.furl(data["callback_url"]) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 200) data = jwt.decode( jwe.decrypt(res.json["payload"].encode("utf-8"), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM, )["data"] assert_equal(data["auth"], views.make_auth(self.user)) assert_equal(data["credentials"], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data["settings"], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for("create_waterbutler_log", _absolute=True)) observed_url = furl.furl(data["callback_url"]) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider="queenhub") res = self.app.get(url, expect_errors=True, auth=self.user.auth) assert_equal(res.status_code, 400) @mock.patch("website.addons.base.views.cas.get_client") def test_auth_bad_bearer_token(self, mock_cas_client): mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False))) url = self.build_url() res = self.app.get(url, headers={"Authorization": "Bearer invalid_access_token"}, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = AddonGitHubOauthSettings(github_user_id='john') self.oauth_settings.save() self.user_addon.oauth_settings = self.oauth_settings self.user_addon.oauth_access_token = 'secret' self.user_addon.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.save() def build_url(self, **kwargs): options = {'payload': jwe.encrypt(jwt.encode({'data': dict(dict( action='download', nid=self.node._id, provider=self.node_addon.config.short_name, ), **kwargs), 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION), }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY)} return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.app.get(url, auth=self.user.auth) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 200) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.app.get(url, expect_errors=True, auth=self.user.auth) assert_equal(res.status_code, 400) @mock.patch('website.addons.base.views.cas.get_client') def test_auth_bad_bearer_token(self, mock_cas_client): mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False))) url = self.build_url() res = self.app.get(url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={"auth_user_id": self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon("github") self.user_addon = self.user.get_addon("github") self.oauth_settings = GitHubAccountFactory(display_name="john") self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon("github", self.auth_obj) self.node_addon = self.node.get_addon("github") self.node_addon.user = "******" self.node_addon.repo = "youre-my-best-friend" self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={"id": self.user._id}, action="create", provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = {key: value for key, value in options.iteritems() if value is not None} message, signature = signing.default_signer.sign_payload(options) return {"payload": message, "signature": signature} @mock.patch("website.notifications.events.files.FileAdded.perform") def test_add_log(self, mock_perform): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}) nlogs = len(self.node.logs) self.app.put_json(url, payload, headers={"Content-Type": "application/json"}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, "perform not called") def test_add_log_missing_args(self): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}, auth=None) nlogs = len(self.node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}, auth={"id": None}) nlogs = len(self.node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = "pizza" node = ProjectFactory(creator=self.user) url = node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}) nlogs = len(node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}, action="dance") nlogs = len(self.node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_action_file_rename(self): url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload( action="rename", metadata={"path": "foo"}, source={ "materialized": "foo", "provider": "github", "node": {"_id": self.node._id}, "name": "new.txt", "kind": "file", }, destination={ "path": "foo", "materialized": "foo", "provider": "github", "node": {"_id": self.node._id}, "name": "old.txt", "kind": "file", }, ) self.app.put_json(url, payload, headers={"Content-Type": "application/json"}) self.node.reload() assert_equal(self.node.logs[-1].action, "github_addon_file_renamed")