예제 #1
0
 def test_validate_token(self, token, valid):
     """Validate that parseable token must have view scope and that an unparseable token is considered valid"""
     if valid:
         SynapseAuthTokenCredentials._validate_token(token)
     else:
         pytest.raises(SynapseAuthenticationError,
                       SynapseAuthTokenCredentials._validate_token, token)
    def _create_synapse_credential(self, syn, username, password, api_key,
                                   auth_token):
        if username is not None:
            if password is not None:
                retrieved_session_token = syn._getSessionToken(
                    email=username, password=password)
                return SynapseApiKeyCredentials(
                    syn._getAPIKey(retrieved_session_token), username)

            elif auth_token is None and api_key is not None:
                # auth token takes precedence over api key
                return SynapseApiKeyCredentials(api_key, username)

        if auth_token is not None:
            credentials = SynapseAuthTokenCredentials(auth_token)
            profile = syn.restGET('/userProfile', auth=credentials)
            profile_username = profile.get('userName')

            if username and username != profile_username:
                # if a username is not required when logging in with an auth token however if both are provided
                # raise an error if they do not correspond to avoid any ambiguity about what profile was logged in
                raise SynapseAuthenticationError(
                    'username and auth_token both provided but username does not match token profile'
                )

            credentials.username = profile_username
            return credentials

        return None
예제 #3
0
 def test_tokens_validated(self, mocker):
     """Validate that tokens are validated when a credentials object is created"""
     token = 'foo'
     mock_validate_token = mocker.patch.object(SynapseAuthTokenCredentials,
                                               '_validate_token')
     SynapseAuthTokenCredentials(token)
     mock_validate_token.assert_called_once_with(token)
예제 #4
0
 def test_get_from_keyring(self, mock_keyring_get_password):
     mock_keyring_get_password.return_value = self.auth_token
     credentials = SynapseAuthTokenCredentials.get_from_keyring(
         self.username)
     mock_keyring_get_password.assert_called_once_with(
         self.KEYRING_NAME,
         self.username,
     )
     assert credentials.username == self.username
     assert credentials.secret == self.auth_token
    def _get_auth_info(self, syn, user_login_args):
        username = None
        password = None
        api_key = None
        auth_token = None

        if not user_login_args.skip_cache:
            username = user_login_args.username or cached_sessions.get_most_recent_user(
            )
            if username:
                api_creds = SynapseApiKeyCredentials.get_from_keyring(username)
                auth_token_creds = SynapseAuthTokenCredentials.get_from_keyring(
                    username)

                api_key = api_creds.secret if api_creds else None
                auth_token = auth_token_creds.secret if auth_token_creds else None

        return username, password, api_key, auth_token
예제 #6
0
 def test_username_setter(self):
     credentials = SynapseAuthTokenCredentials(self.auth_token)
     assert credentials.username is None
     credentials.username = self.username
     assert credentials.username is self.username
예제 #7
0
 def setup(self):
     self.username = "******"
     self.auth_token = 'opensesame'
     self.credentials = SynapseAuthTokenCredentials(self.auth_token,
                                                    username=self.username)
     self.KEYRING_NAME = 'SYNAPSE.ORG_CLIENT_AUTH_TOKEN'
예제 #8
0
class TestSynapseAuthTokenCredentials:
    def setup(self):
        self.username = "******"
        self.auth_token = 'opensesame'
        self.credentials = SynapseAuthTokenCredentials(self.auth_token,
                                                       username=self.username)
        self.KEYRING_NAME = 'SYNAPSE.ORG_CLIENT_AUTH_TOKEN'

    def test_username(self):
        assert self.username == self.credentials.username

    def test_username_setter(self):
        credentials = SynapseAuthTokenCredentials(self.auth_token)
        assert credentials.username is None
        credentials.username = self.username
        assert credentials.username is self.username

    def test_secret(self):
        assert self.credentials.secret == self.auth_token

    def test_call(self):
        """Test the __call__ method used by requests.auth"""

        initial_headers = {'existing': 'header'}
        auth_header = {'Authorization': f"Bearer {self.auth_token}"}

        request = MagicMock(spec=requests.Request)
        request.headers = initial_headers

        self.credentials(request)

        assert request.headers == {**initial_headers, **auth_header}

    def test_repr(self):
        assert (
            f"SynapseAuthTokenCredentials(username='******', token='{self.auth_token}')"
            == repr(self.credentials))

    @patch.object(keyring, 'get_password')
    def test_get_from_keyring(self, mock_keyring_get_password):
        mock_keyring_get_password.return_value = self.auth_token
        credentials = SynapseAuthTokenCredentials.get_from_keyring(
            self.username)
        mock_keyring_get_password.assert_called_once_with(
            self.KEYRING_NAME,
            self.username,
        )
        assert credentials.username == self.username
        assert credentials.secret == self.auth_token

    @patch.object(keyring, 'delete_password')
    def test_delete_from_keyring(self, mock_keyring_delete_password):
        self.credentials.delete_from_keyring()
        mock_keyring_delete_password.assert_called_once_with(
            self.KEYRING_NAME,
            self.username,
        )

    @patch.object(keyring, 'set_password')
    def test_store_to_keyring(self, mock_keyring_set_password):
        self.credentials.store_to_keyring()
        mock_keyring_set_password.assert_called_once_with(
            self.KEYRING_NAME,
            self.username,
            self.auth_token,
        )

    def test_tokens_validated(self, mocker):
        """Validate that tokens are validated when a credentials object is created"""
        token = 'foo'
        mock_validate_token = mocker.patch.object(SynapseAuthTokenCredentials,
                                                  '_validate_token')
        SynapseAuthTokenCredentials(token)
        mock_validate_token.assert_called_once_with(token)

    @pytest.mark.parametrize(
        "token,valid",
        [
            # valid because not parseable at all.
            # we deem these valid to future-proof against a change to the token format that may not be parseable
            # in the same way (or at all)
            ('', True),
            ('thisisnotatoken', True),

            # invalid, parseable but do not contain view scope
            ('eyJ0eXAiOiJKV1QiLCJraWQiOiJXN05OOldMSlQ6SjVSSzpMN1RMOlQ3TDc6M1ZYNjpKRU9VOjY0NFI6VTNJWDo1S1oyOjdaQ0s6RlBUSCIsImFsZyI6IlJTMjU2In0.eyJhY2Nlc3MiOnsic2NvcGUiOlsibW9kaWZ5Il0sIm9pZGNfY2xhaW1zIjp7fX0sInRva2VuX3R5cGUiOiJQRVJTT05BTF9BQ0NFU1NfVE9LRU4iLCJpc3MiOiJodHRwczovL3JlcG8tcHJvZC0zNDQtMC5wcm9kLnNhZ2ViYXNlLm9yZy9hdXRoL3YxIiwiYXVkIjoiMCIsIm5iZiI6MTYxMzU4NTY5MywiaWF0IjoxNjEzNTg1NjkzLCJqdGkiOiI2MTMiLCJzdWIiOiIzNDA1MDk1In0.VFHau1pQJo1zCnK99R5QDY8zivwQg2S9K-aBKsYGpGwXlUuoQXAll9rjFo8ylz0Yy2qjVihCCxHZVqDOAnb_qjNYl2ZDO3C2QSACDDdITQM0lxVD1iuPoHtjM0Z6e1L4pTBOxpI2BqAlyXKV3se7E7Ix54E6JyVDTSACvOphwiM6Vkg5qmYHd8KWQXDXJRPG-ieQW4hXjbWElzaaQpUBGhesqVuZTgyAB1OIkWtJlirkLtxRXlXHsZ9jaNyrhtpscgu527kg2mIR_PePaEan3St-dMvRdggKrDGUmaxmLI68842eff__DRRJLiNdog4UJR5cbQP_9lFbv0l7ev5hEA',
             False),  # noqa
            ('eyJ0eXAiOiJKV1QiLCJraWQiOiJXN05OOldMSlQ6SjVSSzpMN1RMOlQ3TDc6M1ZYNjpKRU9VOjY0NFI6VTNJWDo1S1oyOjdaQ0s6RlBUSCIsImFsZyI6IlJTMjU2In0.eyJhY2Nlc3MiOnsic2NvcGUiOlsibW9kaWZ5Il0sIm9pZGNfY2xhaW1zIjp7fX0sInRva2VuX3R5cGUiOiJQRVJTT05BTF9BQ0NFU1NfVE9LRU4iLCJpc3MiOiJodHRwczovL3JlcG8tcHJvZC0zNDQtMC5wcm9kLnNhZ2ViYXNlLm9yZy9hdXRoL3YxIiwiYXVkIjoiMCIsIm5iZiI6MTYxMzU4NTY5MywiaWF0IjoxNjEzNTg1NjkzLCJqdGkiOiI2MTMiLCJzdWIiOiIzNDA1MDk1In0.VFHau1pQJo1zCnK99R5QDY8zivwQg2S9K - aBKsYGpGwXlUuoQXAll9rjFo8ylz0Yy2qjVihCCxHZVqDOAnb_qjNYl2ZDO3C2QSACDDdITQM0lxVD1iuPoHtjM0Z6e1L4pTBOxpI2BqAlyXKV3se7E7Ix54E6JyVDTSACvOphwiM6Vkg5qmYHd8KWQXDXJRPG - ieQW4hXjbWElzaaQpUBGhesqVuZTgyAB1OIkWtJlirkLtxRXlXHsZ9jaNyrhtpscgu527kg2mIR_PePaEan3St - dMvRdggKrDGUmaxmLI68842eff__DRRJLiNdog4UJR5cbQP_9lFbv0l7ev5hEA',
             False),  # noqa

            # valid, contain view scope
            ('eyJ0eXAiOiJKV1QiLCJraWQiOiJXN05OOldMSlQ6SjVSSzpMN1RMOlQ3TDc6M1ZYNjpKRU9VOjY0NFI6VTNJWDo1S1oyOjdaQ0s6RlBUSCIsImFsZyI6IlJTMjU2In0.eyJhY2Nlc3MiOnsic2NvcGUiOlsidmlldyJdLCJvaWRjX2NsYWltcyI6e319LCJ0b2tlbl90eXBlIjoiUEVSU09OQUxfQUNDRVNTX1RPS0VOIiwiaXNzIjoiaHR0cHM6Ly9yZXBvLXByb2QtMzQ0LTAucHJvZC5zYWdlYmFzZS5vcmcvYXV0aC92MSIsImF1ZCI6IjAiLCJuYmYiOjE2MTM1ODUxNjIsImlhdCI6MTYxMzU4NTE2MiwianRpIjoiNjEyIiwic3ViIjoiMzQwNTA5NSJ9.rNm-SlmWMP4039fcSpnoDNbu9hnkCfoQ0D4O4Cvd0PPlods6ww8eIaCrzfADZ4Uk5vb58R4pW0ZcZmx3mnwVA3rNnLFrgj8BwSwTFiazGoSJ4GWu5bqEviRxP1FD5fKsQHa3EOjd9Zj9u4AvygywWAH97YflNdALH--4aSgeNVcDBldVw5oR_r09j9vXAioeoSW3Ty4QUtIH05cFbWKJmzmZy8K14JIWxj5Dpw6NvfkQbcNuDDEZ2If8hTVr3AyNrDtAZwdp_fNX26caXkWeHWCYUQKv_KUxzj34CZHOu4eeuTSlM0ozfUmrq0LpK7W05WtUEaIoVq7WeNon9yFjLQ',
             True),  # noqa
            ('eyJ0eXAiOiJKV1QiLCJraWQiOiJXN05OOldMSlQ6SjVSSzpMN1RMOlQ3TDc6M1ZYNjpKRU9VOjY0NFI6VTNJWDo1S1oyOjdaQ0s6RlBUSCIsImFsZyI6IlJTMjU2In0.eyJhY2Nlc3MiOnsic2NvcGUiOlsidmlldyIsImRvd25sb2FkIiwibW9kaWZ5Il0sIm9pZGNfY2xhaW1zIjp7fX0sInRva2VuX3R5cGUiOiJQRVJTT05BTF9BQ0NFU1NfVE9LRU4iLCJpc3MiOiJodHRwczovL3JlcG8tcHJvZC0zNDQtMC5wcm9kLnNhZ2ViYXNlLm9yZy9hdXRoL3YxIiwiYXVkIjoiMCIsIm5iZiI6MTYxMzU5Nzc0OSwiaWF0IjoxNjEzNTk3NzQ5LCJqdGkiOiI2MTQiLCJzdWIiOiIzNDA1MDk1In0.s_oB1PDOmZOQ43ALol6krcvs32QSR-sTbHd7wwFWgK9KActjpoqoSoypqYqMd4W5qIr0r633Pucc7KMZMK8jfZXSBAJsuBOXrJ5-4g2dwXib8TX_wWqXj6ten241_qOCVqWzEP9X3aIlAVTMExrIxaj3ReF_NKnVmgsk00L73UPezlG8OUBZBbG9_hvzgBObhqRhkYLA3-HwxuYtxOJfYz9iaJmDJ6xCG7VlEj2SZnBSt2tmScOo0FPCIZYFSvl9neNg9ITSD_B5AuigLHJDLQZD6goGCnB8StSa8rDGa8aCj_G9eM4bTIqdVKf3kctGtggbRQJ88JFVbsNCZNgvQ',
             True),  # noqa
        ])
    def test_validate_token(self, token, valid):
        """Validate that parseable token must have view scope and that an unparseable token is considered valid"""
        if valid:
            SynapseAuthTokenCredentials._validate_token(token)
        else:
            pytest.raises(SynapseAuthenticationError,
                          SynapseAuthTokenCredentials._validate_token, token)