예제 #1
0
    def test_authorize(self):
        """Testing CodebaseHQ.authorize"""
        hosting_account = self.create_hosting_account(data={})

        with self.setup_http_test(payload=b'{}',
                                  hosting_account=hosting_account,
                                  expected_http_calls=1) as ctx:
            self.assertFalse(ctx.service.is_authorized())

            ctx.service.authorize(
                username='******',
                password='******',
                credentials={
                    'domain': 'mydomain',
                    'api_key': 'abc123',
                })

        ctx.assertHTTPCall(
            0,
            url='https://api3.codebasehq.com/users/myuser/public_keys',
            username='******',
            password='******',
            headers={
                'Accept': 'application/xml',
            })

        self.assertEqual(set(six.iterkeys(hosting_account.data)),
                         {'api_key', 'domain', 'password'})
        self.assertEqual(decrypt_password(hosting_account.data['api_key']),
                         'abc123')
        self.assertEqual(hosting_account.data['domain'], 'mydomain')
        self.assertEqual(decrypt_password(hosting_account.data['password']),
                         'mypass')
        self.assertTrue(ctx.service.is_authorized())
예제 #2
0
    def _get_password(self):
        """Returns the password for the repository.

        If a password is stored and encrypted, it will be decrypted and
        returned.

        If the stored password is in plain-text, then it will be encrypted,
        stored in the database, and returned.
        """
        password = self.encrypted_password

        # NOTE: Due to a bug in 2.0.9, it was possible to get a string of
        #       "\tNone", indicating no password. We have to check for this.
        if not password or password == '\tNone':
            password = None
        elif password.startswith(self.ENCRYPTED_PASSWORD_PREFIX):
            password = password[len(self.ENCRYPTED_PASSWORD_PREFIX):]

            if password:
                password = decrypt_password(password)
            else:
                password = None
        else:
            # This is a plain-text password. Convert it.
            self.password = password
            self.save(update_fields=['encrypted_password'])

        return password
예제 #3
0
    def test_decrypt_password(self):
        """Testing decrypt_password"""
        # The encrypted value was made with PyCrypto, to help with
        # compatibility testing from older installs.
        encrypted = b'AjsUGevO3UiVH7iN3zO9vxvqr5X5ozuAbOUByTATsitkhsih1Zc='

        self.assertEqual(decrypt_password(encrypted), self.PLAIN_TEXT)
예제 #4
0
    def test_authorize(self):
        """Testing Unfuddle.authorize"""
        hosting_account = self.create_hosting_account(data={})

        with self.setup_http_test(payload=b'{}',
                                  hosting_account=hosting_account,
                                  expected_http_calls=1) as ctx:
            self.assertFalse(ctx.service.is_authorized())

            ctx.service.authorize(username='******',
                                  password='******',
                                  unfuddle_account_domain='mydomain')

        ctx.assertHTTPCall(
            0,
            url='https://mydomain.unfuddle.com/api/v1/account/',
            username='******',
            password='******',
            headers={
                'Accept': 'application/json',
            })

        self.assertIn('password', hosting_account.data)
        self.assertNotEqual(hosting_account.data['password'], 'abc123')
        self.assertEqual(decrypt_password(hosting_account.data['password']),
                         'abc123')
        self.assertTrue(ctx.service.is_authorized())
예제 #5
0
    def _get_api_version(self, hosting_url):
        """Return the version of the API supported by the given server.

        This method will cache the result.

        Args:
            hosting_url (unicode):
                The URL of the GitLab server.

        Returns:
            unicode:
            The version of the API as a string.

            It is returned as a string because
            :py:func:`djblets.cache.backend.cache_memoize` does not work on
            integer results.
        """
        headers = {}

        if self.account.data and 'private_token' in self.account.data:
            headers[b'PRIVATE-TOKEN'] = decrypt_password(
                self.account.data['private_token'])

        return cache_memoize(
            'gitlab-api-version:%s' % hosting_url,
            expiration=3600,
            lookup_callable=lambda: self._try_api_versions(
                hosting_url,
                headers=headers,
                path='/projects?per_page=1',
            )[0])
예제 #6
0
 def test_encrypt_password(self):
     """Testing encrypt_password"""
     # The encrypted value will change every time, since the iv changes,
     # so we can't compare a direct value. Instead, we need to ensure that
     # we can decrypt what we encrypt.
     self.assertEqual(
         decrypt_password(encrypt_password(self.PLAIN_TEXT)),
         self.PLAIN_TEXT)
예제 #7
0
    def test_decrypt_password_with_custom_key(self):
        """Testing decrypt_password with custom key"""
        # The encrypted value was made with PyCrypto, to help with
        # compatibility testing from older installs.
        encrypted = b'/pOO3VWHRXd1ZAeHZo8MBGQsNClD4lS7XK9WAydt8zW/ob+e63E='

        self.assertEqual(decrypt_password(encrypted, key=self.CUSTOM_KEY),
                         self.PLAIN_TEXT)
예제 #8
0
    def _get_private_token(self):
        """Return the private token used for authentication.

        Returns:
            unicode:
            The API token.
        """
        return decrypt_password(self.account.data['private_token'])
예제 #9
0
    def test_encrypt_password_with_custom_key(self):
        """Testing encrypt_password with custom key"""
        # The encrypted value will change every time, since the iv changes,
        # so we can't compare a direct value. Instead, we need to ensure that
        # we can decrypt what we encrypt.
        encrypted = encrypt_password(self.PLAIN_TEXT, key=self.CUSTOM_KEY)

        self.assertEqual(decrypt_password(encrypted, key=self.CUSTOM_KEY),
                         self.PLAIN_TEXT)
예제 #10
0
    def test_authorize(self):
        """Testing Codebase HQ authorization password storage"""
        account = self._get_hosting_account()
        service = account.service

        self.assertFalse(service.is_authorized())

        self._authorize(service)

        self.assertIn('api_key', account.data)
        self.assertIn('domain', account.data)
        self.assertIn('password', account.data)
        self.assertEqual(decrypt_password(account.data['api_key']),
                         'abc123')
        self.assertEqual(account.data['domain'], 'mydomain')
        self.assertEqual(decrypt_password(account.data['password']),
                         'mypass')
        self.assertTrue(service.is_authorized())
예제 #11
0
    def api_get(self, url, username=None, password=None, json=True, *args,
                **kwargs):
        """Make a request to the API and return the result.

        Args:
            url (unicode):
                The URL to make the request against.

            username (unicode, optional):
                The username to use when making the request. If not provided,
                the account username will be used.

                This argument must be passed when authorizing.

            password (unicode, optional):
                The password to use when making the request. If not provided,
                the account password will be used.

                This argument must be passed when authorizing.

            json (bool, optional):
                Whether or not to interpret the response as JSON. Defaults to
                ``True``.

            *args (tuple):
                Additional positional arguments to pass to the HTTP request
                method.

            **kwargs (dict):
                Additional keyword arguments to pass to the HTTP request
                method.

        Returns:
            object:
            One of the following:

            * If ``json`` is ``True``, the parsed response (:py:class:`dict`).
            * Otherwise, the raw response (:py:class:`unicode`).
        """
        if json:
            method = self.json_get
        else:
            method = self.http_get

        if username is None or password is None:
            username = self.account.username
            password = decrypt_password(
                self.account.data['gerrit_http_password'])

        return method(
            url,
            username=username,
            password=password,
            *args,
            **kwargs
        )[0]
예제 #12
0
    def get_password(self):
        """Return the password for this account.

        This is needed for Perforce and Subversion.

        Returns:
            unicode:
            The stored password for the account.
        """
        return decrypt_password(self.account.data['password'])
예제 #13
0
    def api_get(self, url, raw_content=False):
        """Perform an HTTP GET request to the API.

        Args:
            url (unicode):
                The full URL to the API resource.

            raw_content (bool, optional):
                If set to ``True``, the raw content of the result will be
                returned, instead of a parsed XML result.

        Returns:
            object:
            The parsed content of the result, as a dictionary, or the raw
            bytes content if ``raw_content`` is ``True``.
        """
        hosting_service = self.hosting_service

        try:
            account_data = hosting_service.account.data
            api_username = '******' % (account_data['domain'],
                                      hosting_service.account.username)
            api_key = decrypt_password(account_data['api_key'])

            response = self.http_get(
                url,
                username=api_username,
                password=api_key,
                headers={
                    'Accept': self.API_MIMETYPE,
                })
            data = response.data

            if raw_content:
                return data
            else:
                return self.parse_xml(data)
        except HTTPError as e:
            data = e.read()
            msg = six.text_type(e)

            rsp = self.parse_xml(data)

            if rsp and 'errors' in rsp:
                errors = rsp['errors']

                if 'error' in errors:
                    msg = errors['error']

            if e.code == 401:
                raise AuthorizationError(msg)
            else:
                raise HostingServiceAPIError(msg, http_code=e.code, rsp=rsp)
        except URLError as e:
            raise HostingServiceAPIError(e.reason)
예제 #14
0
    def api_get(self, url, raw_content=False):
        """Perform an HTTP GET request to the API.

        Args:
            url (unicode):
                The full URL to the API resource.

            raw_content (bool, optional):
                If set to ``True``, the raw content of the result will be
                returned, instead of a parsed XML result.

        Returns:
            object:
            The parsed content of the result, as a dictionary, or the raw
            bytes content if ``raw_content`` is ``True``.
        """
        hosting_service = self.hosting_service

        try:
            account_data = hosting_service.account.data
            api_username = '******' % (account_data['domain'],
                                      hosting_service.account.username)
            api_key = decrypt_password(account_data['api_key'])

            data, headers = self.http_get(
                url,
                username=api_username,
                password=api_key,
                headers={
                    'Accept': self.API_MIMETYPE,
                })

            if raw_content:
                return data
            else:
                return self.parse_xml(data)
        except HTTPError as e:
            data = e.read()
            msg = six.text_type(e)

            rsp = self.parse_xml(data)

            if rsp and 'errors' in rsp:
                errors = rsp['errors']

                if 'error' in errors:
                    msg = errors['error']

            if e.code == 401:
                raise AuthorizationError(msg)
            else:
                raise HostingServiceAPIError(msg, http_code=e.code, rsp=rsp)
        except URLError as e:
            raise HostingServiceAPIError(e.reason)
예제 #15
0
    def test_encrypt_password_with_custom_key(self):
        """Testing encrypt_password with custom key"""
        # The encrypted value will change every time, since the iv changes,
        # so we can't compare a direct value. Instead, we need to ensure that
        # we can decrypt what we encrypt.
        encrypted = encrypt_password(self.PASSWORD_UNICODE,
                                     key=self.CUSTOM_KEY)
        self.assertIsInstance(encrypted, str)

        decrypted = decrypt_password(encrypted, key=self.CUSTOM_KEY)
        self.assertIsInstance(decrypted, str)
        self.assertEqual(decrypted, self.PASSWORD_UNICODE)
예제 #16
0
    def api_get(self, url, raw_content=False):
        try:
            response = self.client.http_get(url,
                                            username=self.account.username,
                                            password=decrypt_password(
                                                self.account.data['password']))

            if raw_content:
                return response.data
            else:
                return response.json
        except HTTPError as e:
            self._check_api_error(e)
예제 #17
0
    def test_authorize(self):
        """Testing Beanstalk.authorize"""
        account = self.create_hosting_account(data={})
        service = account.service

        self.assertFalse(service.is_authorized())

        service.authorize('myuser', 'abc123', None)

        self.assertIn('password', account.data)
        self.assertNotEqual(account.data['password'], 'abc123')
        self.assertEqual(decrypt_password(account.data['password']), 'abc123')
        self.assertTrue(service.is_authorized())
예제 #18
0
    def api_get(self, url, raw_content=False):
        try:
            response = self.client.http_get(
                url,
                username=self.account.username,
                password=decrypt_password(self.account.data['password']))

            if raw_content:
                return response.data
            else:
                return response.json
        except HTTPError as e:
            self._check_api_error(e)
예제 #19
0
    def get_private_token(self):
        """Return the private token used for authentication.

        Returns:
            unicode:
            The private token, or ``None`` if one wasn't set.
        """
        private_token = self.account.data.get('private_token')

        if not private_token:
            return None

        return decrypt_password(private_token)
예제 #20
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self.client.http_get(
                url,
                username=self.account.username,
                password=decrypt_password(self.account.data['password']))

            if raw_content:
                return data
            else:
                return json.loads(data)
        except HTTPError as e:
            self._check_api_error(e)
예제 #21
0
    def test_authorize(self):
        """Testing Beanstalk.authorize"""
        account = self.create_hosting_account(data={})
        service = account.service

        self.assertFalse(service.is_authorized())

        service.authorize('myuser', 'abc123', None)

        self.assertIn('password', account.data)
        self.assertNotEqual(account.data['password'], 'abc123')
        self.assertEqual(decrypt_password(account.data['password']), 'abc123')
        self.assertTrue(service.is_authorized())
예제 #22
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self.client.http_get(
                url,
                username=self.account.username,
                password=decrypt_password(self.account.data['password']))

            if raw_content:
                return data
            else:
                return json.loads(data)
        except HTTPError as e:
            self._check_api_error(e)
예제 #23
0
    def get_password(self):
        """Return the password for this account.

        This is used primarily for Subversion repositories, so that direct
        access can be performed in order to fetch properties and other
        information.

        This does not return the API key.

        Returns:
            unicode:
            The account password for repository access.
        """
        return decrypt_password(self.account.data['password'])
예제 #24
0
    def get_password(self):
        """Return the password for this account.

        This is used primarily for Subversion repositories, so that direct
        access can be performed in order to fetch properties and other
        information.

        This does not return the API key.

        Returns:
            unicode:
            The account password for repository access.
        """
        return decrypt_password(self.account.data['password'])
예제 #25
0
    def get_http_credentials(self,
                             account,
                             username=None,
                             password=None,
                             **kwargs):
        """Return credentials used to authenticate with GitHub.

        Unless an explicit username and password is provided, this will
        use the ones stored for the account.

        Args:
            account (reviewboard.hostingsvcs.models.HostingServiceAccount):
                The stored authentication data for the service.

            username (unicode, optional):
                An explicit username passed by the caller. This will override
                the data stored in the account, if both a username and
                password are provided.

            password (unicode, optional):
                An explicit password passed by the caller. This will override
                the data stored in the account, if both a username and
                password are provided.

            **kwargs (dict, unused):
                Additional keyword arguments passed in when making the HTTP
                request.

        Returns:
            dict:
            A dictionary of credentials for the request.
        """
        if username is None and password is None:
            if 'personal_token' in account.data:
                username = account.username
                password = decrypt_password(account.data['personal_token'])
            elif ('authorization' in account.data
                  and 'token' in account.data['authorization']):
                username = account.username
                password = account.data['authorization']['token']

        if username is not None and password is not None:
            return {
                'username': username,
                'password': password,
            }

        return {}
예제 #26
0
def get_user_api_token(user):
    """Return the user's API token for I Done This.

    Args:
        user (django.contrib.auth.models.User):
            The user whose API token should be retrieved.

    Returns:
        unicode:
        The user's API token, or ``None`` if the user has not set one.
    """
    try:
        settings = user.get_profile().settings['idonethis']
        return decrypt_password(settings['api_token'])
    except KeyError:
        return None
예제 #27
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self._http_get(
                url, username=self.account.username, password=decrypt_password(self.account.data["password"])
            )

            if raw_content:
                return data
            else:
                return simplejson.loads(data)
        except HTTPError, e:
            # Bitbucket's API documentation doesn't provide any information
            # on an error structure, and the API browser shows that we
            # sometimes get a raw error string, and sometimes raw HTML.
            # We'll just have to return what we get for now.
            raise Exception(e.read())
예제 #28
0
def get_user_api_token(user):
    """Return the user's API token for I Done This.

    Args:
        user (django.contrib.auth.models.User):
            The user whose API token should be retrieved.

    Returns:
        unicode:
        The user's API token, or ``None`` if the user has not set one.
    """
    try:
        settings = user.get_profile().settings['idonethis']
        return decrypt_password(settings['api_token'])
    except KeyError:
        return None
예제 #29
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self._http_get(
                url,
                username=self.account.username,
                password=decrypt_password(self.account.data['password']))

            if raw_content:
                return data
            else:
                return json.loads(data)
        except HTTPError as e:
            # Bitbucket's API documentation doesn't provide any information
            # on an error structure, and the API browser shows that we
            # sometimes get a raw error string, and sometimes raw HTML.
            # We'll just have to return what we get for now.
            raise Exception(e.read())
예제 #30
0
    def test_authorize(self):
        """Testing Bitbucket.authorize"""
        hosting_account = self.create_hosting_account(data={})

        with self.setup_http_test(payload=b'{}',
                                  hosting_account=hosting_account,
                                  expected_http_calls=1) as ctx:
            self.assertFalse(ctx.service.is_authorized())
            ctx.service.authorize(username='******', password='******')

        self.assertIn('password', hosting_account.data)
        self.assertNotEqual(hosting_account.data['password'], 'abc123')
        self.assertEqual(decrypt_password(hosting_account.data['password']),
                         'abc123')
        self.assertTrue(ctx.service.is_authorized())

        ctx.assertHTTPCall(0,
                           url='https://bitbucket.org/api/2.0/user',
                           username='******',
                           password='******')
예제 #31
0
    def get_http_credentials(self,
                             account,
                             username=None,
                             password=None,
                             **kwargs):
        """Return credentials used to authenticate with the service.

        Unless an explicit username and password is provided, this will
        use the ones stored for the account.

        Args:
            account (reviewboard.hostingsvcs.models.HostingServiceAccount):
                The stored authentication data for the service.

            username (unicode, optional):
                An explicit username passed by the caller. This will override
                the data stored in the account, if both a username and
                password are provided.

            password (unicode, optional):
                An explicit password passed by the caller. This will override
                the data stored in the account, if both a username and
                password are provided.

            **kwargs (dict, unused):
                Additional keyword arguments passed in when making the HTTP
                request.

        Returns:
            dict:
            A dictionary of credentials for the request.
        """
        if username is None and password is None:
            username = account.username
            password = decrypt_password(account.data['gerrit_http_password'])

        return super(GerritClient,
                     self).get_http_credentials(account=account,
                                                username=username,
                                                password=password)
예제 #32
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self._http_get(
                url, username=self.account.username, password=decrypt_password(self.account.data["password"])
            )

            if raw_content:
                return data
            else:
                return json.loads(data)
        except HTTPError as e:
            data = e.read()

            try:
                rsp = json.loads(data)
            except:
                rsp = None

            if rsp and "errors" in rsp:
                raise Exception("; ".join(rsp["errors"]))
            else:
                raise Exception(six.text_type(e))
예제 #33
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self._http_get(
                url,
                username=self.account.username,
                password=decrypt_password(self.account.data['password']))

            if raw_content:
                return data
            else:
                return json.loads(data)
        except HTTPError as e:
            data = e.read()

            try:
                rsp = json.loads(data)
            except:
                rsp = None

            if rsp and 'errors' in rsp:
                raise Exception('; '.join(rsp['errors']))
            else:
                raise Exception(str(e))
예제 #34
0
    def _api_get(self, url, raw_content=False):
        try:
            data, headers = self._http_get(
                url,
                username=self.account.username,
                password=decrypt_password(self.account.data['password']))

            if raw_content:
                return data
            else:
                return json.loads(data)
        except HTTPError as e:
            data = e.read()

            try:
                rsp = json.loads(data)
            except:
                rsp = None

            if rsp and 'errors' in rsp:
                raise Exception('; '.join(rsp['errors']))
            else:
                raise Exception(six.text_type(e))
예제 #35
0
    def get_password(self):
        """Returns the password for this account.

        This is needed for API calls and for Subversion.
        """
        return decrypt_password(self.account.data['password'])
예제 #36
0
 def _get_private_token(self):
     """Returns the private token used for authentication."""
     return decrypt_password(self.account.data["private_token"])
예제 #37
0
    def get_password(self):
        """Returns the password for this account.

        This is needed for API calls and for Subversion.
        """
        return decrypt_password(self.account.data['password'])
예제 #38
0
 def _get_private_token(self):
     """Returns the private token used for authentication."""
     return decrypt_password(self.account.data['private_token'])