示例#1
0
    def authorize(self, username, password, credentials, *args, **kwargs):
        """Authorize an account for Codebase.

        Codebase usees HTTP Basic Auth with an API username (consisting of the
        Codebase team's domain and the account username) and an API key (for
        the password) for API calls, and a standard username/password for
        Subversion repository access. We need to store all of this.

        Args:
            username (unicode):
                The username to authorize.

            password (unicode):
                The API token used as a password.

            credentials (dict):
                Additional credentials from the authentication form.

            *args (tuple):
                Extra unused positional arguments.

            **kwargs (dict):
                Extra unused keyword arguments.

        Raises:
            reviewboard.hostingsvcs.errors.AuthorizationError:
                The credentials provided were not valid.
        """
        self.account.data.update({
            'domain':
            credentials['domain'],
            'api_key':
            encrypt_password(credentials['api_key']),
            'password':
            encrypt_password(password),
        })

        # Test the account to make sure the credentials are fine. Note that
        # we can only really sanity-check the API token, domain, and username
        # from here. There's no way good way to check the actual password,
        # which we only use for Subversion repositories.
        #
        # This will raise a suitable error message if authorization fails.
        try:
            self.client.api_get_public_keys(username)
        except AuthorizationError:
            raise AuthorizationError(
                ugettext('One or more of the credentials provided were not '
                         'accepted by Codebase.'))

        self.account.save()
示例#2
0
    def authorize(self, username, password, credentials, *args, **kwargs):
        """Authorize an account for Codebase.

        Codebase usees HTTP Basic Auth with an API username (consisting of the
        Codebase team's domain and the account username) and an API key (for
        the password) for API calls, and a standard username/password for
        Subversion repository access. We need to store all of this.

        Args:
            username (unicode):
                The username to authorize.

            password (unicode):
                The API token used as a password.

            credentials (dict):
                Additional credentials from the authentication form.

            *args (tuple):
                Extra unused positional arguments.

            **kwargs (dict):
                Extra unused keyword arguments.

        Raises:
            reviewboard.hostingsvcs.errors.AuthorizationError:
                The credentials provided were not valid.
        """
        self.account.data.update(
            {
                "domain": credentials["domain"],
                "api_key": encrypt_password(credentials["api_key"]),
                "password": encrypt_password(password),
            }
        )

        # Test the account to make sure the credentials are fine. Note that
        # we can only really sanity-check the API token, domain, and username
        # from here. There's no way good way to check the actual password,
        # which we only use for Subversion repositories.
        #
        # This will raise a suitable error message if authorization fails.
        try:
            self.client.api_get_public_keys(username)
        except AuthorizationError:
            raise AuthorizationError(
                ugettext("One or more of the credentials provided were not " "accepted by Codebase.")
            )

        self.account.save()
    def authorize(self, username, password, *args, **kwargs):
        """Authorize an account on the RB Gateway service.

        This will perform an authentication request against the API. If
        successful, the generated API token will be stored, encrypted, for
        future requests to the API.

        Args:
            username (unicode):
                The username for the account.

            password (unicode):
                The password for the account.

            *args (tuple, unused):
                Unused positional arguments.

            **kwargs (dict, unused):
                Unused keyword arguments.

        Raises:
            reviewboard.hostingsvcs.errors.HostingServiceError:
                Error retrieving the branch information. There may be a more
                specific subclass raised.
        """
        auth_data = self.client.api_authenticate(username, password)

        self.account.data['private_token'] = \
            encrypt_password(auth_data['private_token'])
        self.account.save()
示例#4
0
    def _test_get_file(self, tool_name, revision, base_commit_id,
                       expected_revision):
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(
                url,
                'https://bitbucket.org/api/1.0/repositories/'
                'myuser/myrepo/raw/%s/path'
                % expected_revision)
            return b'My data', {}

        account = self._get_hosting_account()
        service = account.service
        repository = Repository(hosting_account=account,
                                tool=Tool.objects.get(name=tool_name))
        repository.extra_data = {
            'bitbucket_repo_name': 'myrepo',
        }

        account.data['password'] = encrypt_password('abc123')

        self.spy_on(service.client.http_get, call_fake=_http_get)

        result = service.get_file(repository, 'path', revision,
                                  base_commit_id)
        self.assertTrue(service.client.http_get.called)
        self.assertEqual(result, 'My data')
示例#5
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)
示例#6
0
    def save(self, **kwargs):
        """Save the authentication form.

        Args:
            **kwargs (dict):
                Keyword arguments to pass to
                :py:meth`:HostingServiceAuthForm.save()
                <reviewboard.hostingsvcs.forms.HostingServiceAuthForm.save>`.

        Returns:
            reviewboard.hostingsvcs.models.HostingServiceAccount:
            The hosting service account.

        Raises:
            reviewboard.hostingsvcs.errors.AuthorizationError:
                Information needed to authorize was missing, or authorization
                failed.
        """
        hosting_account = super(GerritAuthForm, self).save(save=False,
                                                           **kwargs)

        if not hosting_account.data:
            hosting_account.data = {}

        hosting_account.data['gerrit_http_password'] = encrypt_password(
            self.get_credentials()['password'])
        hosting_account.save()

        return hosting_account
示例#7
0
    def authorize(self, username, password, hosting_url, *args, **kwargs):
        """Authorizes the GitLab repository.

        GitLab uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.
        """
        if self._is_email(username):
            login_key = 'email'
        else:
            login_key = 'login'

        # This will raise an exception if it fails, which the form will
        # catch.
        try:
            rsp, headers = self.client.json_post(
                url=self._build_api_url(hosting_url, 'session'),
                fields={
                    login_key: username,
                    'password': password,
                })
        except HTTPError as e:
            if e.code == 404:
                raise HostingServiceError(
                    ugettext('A GitLab server was not found at the '
                             'provided URL.'))
            elif e.code == 401:
                raise AuthorizationError(
                    ugettext('The username or password is incorrect.'))
            else:
                raise

        self.account.data['private_token'] = \
            encrypt_password(rsp['private_token'])
        self.account.save()
示例#8
0
    def save(self, **kwargs):
        """Save the authentication form.

        Args:
            **kwargs (dict):
                Keyword arguments to pass to
                :py:meth`:HostingServiceAuthForm.save()
                <reviewboard.hostingsvcs.forms.HostingServiceAuthForm.save>`.

        Returns:
            reviewboard.hostingsvcs.models.HostingServiceAccount:
            The hosting service account.

        Raises:
            reviewboard.hostingsvcs.errors.AuthorizationError:
                Information needed to authorize was missing, or authorization
                failed.
        """
        hosting_account = super(GerritAuthForm, self).save(save=False,
                                                           **kwargs)

        if not hosting_account.data:
            hosting_account.data = {}

        hosting_account.data['gerrit_http_password'] = encrypt_password(
            self.get_credentials()['password'])
        hosting_account.save()

        return hosting_account
示例#9
0
    def _test_check_repository_error(self, expected_error, **kwargs):
        def _http_get(service, url, *args, **kwargs):
            if url == 'https://example.com/api/v3/groups?per_page=100':
                payload = [{
                    'id': 1,
                    'name': 'mygroup',
                }]
            elif url == 'https://example.com/api/v3/groups/1':
                payload = {
                    'projects': [
                        {
                            'id': 1,
                            'name': 'myrepo',
                        },
                    ],
                }
            else:
                payload = []

            return json.dumps(payload), {}

        account = self._get_hosting_account(use_url=True)
        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)
        account.data['private_token'] = encrypt_password('abc123')

        try:
            service.check_repository(**kwargs)
            saw_exception = False
        except Exception as e:
            self.assertEqual(six.text_type(e), expected_error)
            saw_exception = True

        self.assertTrue(saw_exception)
示例#10
0
    def _test_get_file_exists(self, tool_name, revision, base_commit_id,
                              expected_revision, expected_found,
                              expected_http_called=True):
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(
                url,
                'https://bitbucket.org/api/1.0/repositories/'
                'myuser/myrepo/raw/%s/path'
                % expected_revision)

            if expected_found:
                return b'{}', {}
            else:
                error = HTTPError(url, 404, 'Not Found', {}, None)
                error.read = lambda: error.msg
                raise error

        account = self._get_hosting_account()
        service = account.service
        repository = Repository(hosting_account=account,
                                tool=Tool.objects.get(name=tool_name))
        repository.extra_data = {
            'bitbucket_repo_name': 'myrepo',
        }

        account.data['password'] = encrypt_password('abc123')

        self.spy_on(service.client.http_get, call_fake=_http_get)

        result = service.get_file_exists(repository, 'path', revision,
                                         base_commit_id)
        self.assertEqual(service.client.http_get.called, expected_http_called)
        self.assertEqual(result, expected_found)
示例#11
0
    def authorize(self, username, password, hosting_url, *args, **kwargs):
        """Authorizes the GitLab repository.

        GitLab uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.
        """
        # This will raise an exception if it fails, which the form will
        # catch.
        try:
            rsp, headers = self._json_post(url=self._build_api_url(
                hosting_url, 'session'),
                                           fields={
                                               'login': username,
                                               'password': password,
                                           })
        except HTTPError as e:
            if e.code == 404:
                raise HostingServiceError(
                    ugettext('A GitLab server was not found at the '
                             'provided URL.'))
            elif e.code == 401:
                raise AuthorizationError(
                    ugettext('The username or password is incorrect.'))
            else:
                raise

        self.account.data['private_token'] = \
            encrypt_password(rsp['private_token'])
        self.account.save()
示例#12
0
    def authorize(self, username, credentials, hosting_url, *args, **kwargs):
        """Authorize the GitLab repository.

        GitLab uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.

        Args:
            username (unicode):
                The username of the account being linked.

            credentials (dict):
                Authentication credentials.

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

            *args (tuple, unused):
                Ignored positional arguments.

            **kwargs (dict, unused):
                Ignored keyword arguments.

        Raises:
            reviewboard.hostingsvcs.errors.AuthorizationError:
                Authorization could not be completed successfully.

            reviewboard.hostingsvcs.errors.HostingServiceError:
                An HTTP or other unexpected error occurred.
        """
        # This will raise an exception if it fails, which the form will
        # catch.
        try:
            self._try_api_versions(hosting_url,
                                   path='/projects?per_page=1',
                                   headers={
                                       'PRIVATE-TOKEN':
                                       credentials['private_token'],
                                   })
        except (AuthorizationError, GitLabAPIVersionError):
            raise
        except HTTPError as e:
            if e.code == 404:
                raise HostingServiceError(
                    ugettext('A GitLab server was not found at the '
                             'provided URL.'))
            else:
                logging.exception(
                    'Unexpected HTTP error when linking GitLab '
                    'account for %s: %s', username, e)
                raise HostingServiceError(
                    ugettext('Unexpected HTTP error %s.') % e.code)
        except Exception as e:
            logging.exception(
                'Unexpected error when linking GitLab account '
                'for %s: %s', username, e)
            raise HostingServiceError(ugettext('Unexpected error "%s"') % e)

        self.account.data['private_token'] = \
            encrypt_password(credentials['private_token'])
        self.account.save()
示例#13
0
    def test_other_user_check_repository(self):
        """Testing Bitbucket other-user check_repository"""
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(
                url,
                'https://bitbucket.org/api/2.0/repositories/someuser/myrepo'
                '?fields=scm')
            return (
                json.dumps({
                    'scm': 'git',
                }),
                {})

        account = self._get_hosting_account()
        service = account.service

        account.data['password'] = encrypt_password('abc123')

        self.spy_on(service.client.http_get, call_fake=_http_get)

        service.check_repository(bitbucket_other_user_username='******',
                                 bitbucket_other_user_repo_name='myrepo',
                                 plan='other-user',
                                 tool_name='Git')
        self.assertTrue(service.client.http_get.called)
示例#14
0
    def authorize(self, username, password, hosting_url, *args, **kwargs):
        """Authorize the Review Board Gateway repository.

        Review Board Gateway uses HTTP Basic Auth, so this will store the
        provided password, encrypted, for use in later API requests.

        Similar to GitLab's API, Review Board Gateway will return a private
        token on session authentication.
        """
        try:
            response = self.client.http_post(url='%s/session' % hosting_url,
                                             username=username,
                                             password=password)
        except HTTPError as e:
            if e.code == 401:
                raise AuthorizationError(
                    ugettext('The username or password is incorrect.'))
            elif e.code == 404:
                raise HostingServiceError(
                    ugettext('A Review Board Gateway server was not found at '
                             'the provided URL.'))
            else:
                logger.exception('Failed authorization at %s/session: %s',
                                 hosting_url, e)

            raise

        self.account.data['private_token'] = \
            encrypt_password(response.json['private_token'])
        self.account.save()
示例#15
0
    def authorize(self, username, password, hosting_url, *args, **kwargs):
        """Authorizes the GitLab repository.

        GitLab uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.
        """
        if self._is_email(username):
            login_key = "email"
        else:
            login_key = "login"

        # This will raise an exception if it fails, which the form will
        # catch.
        try:
            rsp, headers = self.client.json_post(
                url=self._build_api_url(hosting_url, "session"), fields={login_key: username, "password": password}
            )
        except HTTPError as e:
            if e.code == 404:
                raise HostingServiceError(ugettext("A GitLab server was not found at the " "provided URL."))
            elif e.code == 401:
                raise AuthorizationError(ugettext("The username or password is incorrect."))
            else:
                logging.exception("Unexpected HTTP error when linking GitLab " "account for %s: %s", username, e)
                raise HostingServiceError(ugettext("Unexpected HTTP error %s.") % e.code)
        except Exception as e:
            logging.exception("Unexpected error when linking GitLab account " "for %s: %s", username, e)
            raise HostingServiceError(ugettext('Unexpected error "%s"') % e)

        self.account.data["private_token"] = encrypt_password(rsp["private_token"])
        self.account.save()
示例#16
0
    def test_get_branches(self):
        """Testing GitLab get_branches implementation"""
        branches_api_response = json.dumps([
            {
                'name': 'master',
                'commit': {
                    'id': 'ed899a2f4b50b4370feeea94676502b42383c746'
                }
            },
            {
                'name': 'branch1',
                'commit': {
                    'id': '6104942438c14ec7bd21c6cd5bd995272b3faff6'
                }
            },
            {
                'name': 'branch2',
                'commit': {
                    'id': '21b3bcabcff2ab3dc3c9caa172f783aad602c0b0'
                }
            },
            {
                'branch-name': 'branch3',
                'commit': {
                    'id': 'd5a3ff139356ce33e37e73add446f16869741b50'
                }
            }
        ])

        def _http_get(self, *args, **kwargs):
            return branches_api_response, None

        account = self._get_hosting_account(use_url=True)
        account.data['private_token'] = encrypt_password('abc123')

        service = account.service

        repository = Repository(hosting_account=account)
        repository.extra_data = {'gitlab_project_id': 123456}

        self.spy_on(service.client.http_get, call_fake=_http_get)

        branches = service.get_branches(repository)

        self.assertTrue(service.client.http_get.called)
        self.assertEqual(len(branches), 3)
        self.assertEqual(
            branches,
            [
                Branch(id='master',
                       commit='ed899a2f4b50b4370feeea94676502b42383c746',
                       default=True),
                Branch(id='branch1',
                       commit='6104942438c14ec7bd21c6cd5bd995272b3faff6',
                       default=False),
                Branch(id='branch2',
                       commit='21b3bcabcff2ab3dc3c9caa172f783aad602c0b0',
                       default=False)
            ])
示例#17
0
    def authorize(self,
                  username,
                  password,
                  hosting_url=None,
                  local_site_name=None,
                  *args,
                  **kwargs):
        """Authorize an account for the hosting service.

        Args:
            username (unicode):
                The username for the account.

            password (unicode):
                The Personal Access Token for the account.

            hosting_url (unicode):
                The hosting URL for the service, if self-hosted.

            local_site_name (unicode, optional):
                The Local Site name, if any, that the account should be
                bound to.

            *args (tuple):
                Extra unused positional arguments.

            **kwargs (dict):
                Extra keyword arguments containing values from the
                repository's configuration.

        Raises:
            reviewboard.hostingsvcs.errors.AuthorizationError:
                The credentials provided were not valid.
        """
        # Try to reach an API resource with the provided credentials.
        rsp = self.client.http_get('%suser' % self.get_api_url(hosting_url),
                                   username=username,
                                   password=password)

        # Check to make sure this token has all the necessary scopes.
        token_scopes = set(rsp.get_header('x-oauth-scopes', '').split(', '))
        required_scopes = set(self.REQUIRED_SCOPES)
        missing_scopes = required_scopes - token_scopes

        if missing_scopes:
            raise AuthorizationError(
                _('This GitHub Personal Access Token must have the '
                  'following scopes enabled: %(scopes)s') % {
                      'scopes': ', '.join(sorted(missing_scopes)),
                  })

        if 'authorization' in self.account.data:
            # This is an older GitHub linked account, which used the legacy
            # authorizations API to generate the token. This stopped being
            # supported in Review Board 3.0.18.
            del self.account.data['authorization']

        self.account.data['personal_token'] = encrypt_password(password)
        self.account.save()
示例#18
0
    def test_get_commits(self):
        """Testing ReviewBoardGateway get_commits implementation"""
        commits_api_response = json.dumps([{
            'author':
            'myname',
            'id':
            'bfdde95432b3af879af969bd2377dc3e55ee46e6',
            'date':
            '2015-02-13 22:34:01 -0700 -0700',
            'message':
            'mymessage',
            'parent_id':
            '304c53c163aedfd0c0e0933776f09c24b87f5944',
        }, {
            'author':
            'myname',
            'id':
            '304c53c163aedfd0c0e0933776f09c24b87f5944',
            'date':
            '2015-02-13 22:32:42 -0700 -0700',
            'message':
            'mymessage',
            'parent_id':
            'fa1330719893098ae397356e8125c2aa45b49221',
        }, {
            'author': 'anothername',
            'id': 'fa1330719893098ae397356e8125c2aa45b49221',
            'date': '2015-02-12 16:01:48 -0700 -0700',
            'message': 'mymessage',
            'parent_id': '',
        }])

        def _http_get(self, *args, **kwargs):
            return commits_api_response, None

        account = self._get_hosting_account()
        account.data['private_token'] = encrypt_password('abc123')

        repository = Repository(hosting_account=account)
        repository.extra_data = {
            'rbgateway_repo_name': 'myrepo',
        }

        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)

        commits = service.get_commits(
            repository, branch='bfdde95432b3af879af969bd2377dc3e55ee46e6')

        self.assertTrue(service.client.http_get.called)

        self.assertEqual(len(commits), 3)
        self.assertEqual(commits[0].parent, commits[1].id)
        self.assertEqual(commits[1].parent, commits[2].id)
        self.assertEqual(commits[0].date, '2015-02-13 22:34:01 -0700 -0700')
        self.assertEqual(commits[1].id,
                         '304c53c163aedfd0c0e0933776f09c24b87f5944')
        self.assertEqual(commits[2].author_name, 'anothername')
        self.assertEqual(commits[2].parent, '')
示例#19
0
    def test_get_branches(self):
        """Testing GitLab get_branches implementation"""
        branches_api_response = json.dumps([
            {
                'name': 'master',
                'commit': {
                    'id': 'ed899a2f4b50b4370feeea94676502b42383c746'
                }
            },
            {
                'name': 'branch1',
                'commit': {
                    'id': '6104942438c14ec7bd21c6cd5bd995272b3faff6'
                }
            },
            {
                'name': 'branch2',
                'commit': {
                    'id': '21b3bcabcff2ab3dc3c9caa172f783aad602c0b0'
                }
            },
            {
                'branch-name': 'branch3',
                'commit': {
                    'id': 'd5a3ff139356ce33e37e73add446f16869741b50'
                }
            }
        ])

        def _http_get(self, *args, **kwargs):
            return branches_api_response, None

        account = self._get_hosting_account(use_url=True)
        account.data['private_token'] = encrypt_password('abc123')

        service = account.service

        repository = Repository(hosting_account=account)
        repository.extra_data = {'gitlab_project_id': 123456}

        self.spy_on(service.client.http_get, call_fake=_http_get)

        branches = service.get_branches(repository)

        self.assertTrue(service.client.http_get.called)
        self.assertEqual(len(branches), 3)
        self.assertEqual(
            branches,
            [
                Branch(id='master',
                       commit='ed899a2f4b50b4370feeea94676502b42383c746',
                       default=True),
                Branch(id='branch1',
                       commit='6104942438c14ec7bd21c6cd5bd995272b3faff6',
                       default=False),
                Branch(id='branch2',
                       commit='21b3bcabcff2ab3dc3c9caa172f783aad602c0b0',
                       default=False)
            ])
示例#20
0
    def authorize(self, username, password, hosting_url, local_site_name=None, *args, **kwargs):
        """Authorizes the Beanstalk repository.

        Beanstalk uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.
        """
        self.account.data["password"] = encrypt_password(password)
        self.account.save()
 def test_encrypt_password_with_unicode(self):
     """Testing encrypt_password with Unicode string"""
     # 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 = decrypt_password(encrypt_password(self.PASSWORD_UNICODE))
     self.assertIsInstance(encrypted, str)
     self.assertEqual(encrypted, self.PASSWORD_UNICODE)
示例#22
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)
示例#23
0
    def authorize(self, username, password, *args, **kwargs):
        """Authorizes the Bitbucket repository.

        Bitbucket supports HTTP Basic Auth or OAuth for the API. We use
        HTTP Basic Auth for now, and we store provided password,
        encrypted, for use in later API requests.
        """
        self.account.data["password"] = encrypt_password(password)
        self.account.save()
示例#24
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)
示例#25
0
class AssemblaTestCase(HostingServiceTestCase):
    """Base class for Assembla test suites."""

    service_name = 'assembla'
    fixtures = ['test_scmtools']

    default_account_data = {
        'password': encrypt_password('abc123'),
    }
示例#26
0
    def authorize(self, username, password, *args, **kwargs):
        """Authorizes the Bitbucket repository.

        Bitbucket supports HTTP Basic Auth or OAuth for the API. We use
        HTTP Basic Auth for now, and we store provided password,
        encrypted, for use in later API requests.
        """
        self.account.data['password'] = encrypt_password(password)
        self.account.save()
示例#27
0
    def authorize(self, username, password, hosting_url,
                  local_site_name=None, *args, **kwargs):
        """Authorizes the Beanstalk repository.

        Beanstalk uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.
        """
        self.account.data['password'] = encrypt_password(password)
        self.account.save()
示例#28
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)
示例#29
0
    def test_get_commits(self):
        """Testing GitLab get_commits implementation"""
        commits_api_response = json.dumps([{
            'id':
            'ed899a2f4b50b4370feeea94676502b42383c746',
            'author_name':
            'Chester Li',
            'created_at':
            '2015-03-10T11:50:22+03:00',
            'message':
            'Replace sanitize with escape once'
        }, {
            'id':
            '6104942438c14ec7bd21c6cd5bd995272b3faff6',
            'author_name':
            'Chester Li',
            'created_at':
            '2015-03-10T09:06:12+03:00',
            'message':
            'Sanitize for network graph'
        }, {
            'id':
            '21b3bcabcff2ab3dc3c9caa172f783aad602c0b0',
            'author_name':
            'East Coast',
            'created_at':
            '2015-03-04T15:31:18.000-04:00',
            'message':
            'Add a timer to test file'
        }])

        def _http_get(self, *args, **kargs):
            return commits_api_response, None

        account = self._get_hosting_account(use_url=True)
        account.data['private_token'] = encrypt_password('abc123')

        service = account.service

        repository = Repository(hosting_account=account)
        repository.extra_data = {'gitlab_project_id': 123456}

        self.spy_on(service.client.http_get, call_fake=_http_get)

        commits = service.get_commits(
            repository, start='ed899a2f4b50b4370feeea94676502b42383c746')

        self.assertTrue(service.client.http_get.called)
        self.assertEqual(len(commits), 3)
        self.assertEqual(commits[0].id,
                         'ed899a2f4b50b4370feeea94676502b42383c746')
        self.assertNotEqual(commits[0].author_name, 'East Coast')
        self.assertEqual(commits[1].date, '2015-03-10T09:06:12+03:00')
        self.assertNotEqual(commits[1].message,
                            'Replace sanitize with escape once')
        self.assertEqual(commits[2].author_name, 'East Coast')
    def test_get_commits(self):
        """Testing ReviewBoardGateway get_commits implementation"""
        commits_api_response = json.dumps([
            {
                'author': 'myname',
                'id': 'bfdde95432b3af879af969bd2377dc3e55ee46e6',
                'date': '2015-02-13 22:34:01 -0700 -0700',
                'message': 'mymessage',
                'parent_id': '304c53c163aedfd0c0e0933776f09c24b87f5944',
            },
            {
                'author': 'myname',
                'id': '304c53c163aedfd0c0e0933776f09c24b87f5944',
                'date': '2015-02-13 22:32:42 -0700 -0700',
                'message': 'mymessage',
                'parent_id': 'fa1330719893098ae397356e8125c2aa45b49221',
            },
            {
                'author': 'anothername',
                'id': 'fa1330719893098ae397356e8125c2aa45b49221',
                'date': '2015-02-12 16:01:48 -0700 -0700',
                'message': 'mymessage',
                'parent_id': '',
            }
        ])

        def _http_get(self, *args, **kwargs):
            return commits_api_response, None

        account = self._get_hosting_account()
        account.data['private_token'] = encrypt_password('abc123')

        repository = Repository(hosting_account=account)
        repository.extra_data = {
            'rbgateway_repo_name': 'myrepo',
        }

        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)

        commits = service.get_commits(
            repository, branch='bfdde95432b3af879af969bd2377dc3e55ee46e6')

        self.assertTrue(service.client.http_get.called)

        self.assertEqual(len(commits), 3)
        self.assertEqual(commits[0].parent, commits[1].id)
        self.assertEqual(commits[1].parent, commits[2].id)
        self.assertEqual(commits[0].date, '2015-02-13 22:34:01 -0700 -0700')
        self.assertEqual(commits[1].id,
                         '304c53c163aedfd0c0e0933776f09c24b87f5944')
        self.assertEqual(commits[2].author_name, 'anothername')
        self.assertEqual(commits[2].parent, '')
    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, six.text_type)

        decrypted = decrypt_password(encrypted, key=self.CUSTOM_KEY)
        self.assertIsInstance(decrypted, six.text_type)
        self.assertEqual(decrypted, self.PASSWORD_UNICODE)
示例#32
0
    def authorize(self, username, password, unfuddle_account_domain=None, *args, **kwargs):
        """Authorizes the Unfuddle repository.

        Unfuddle uses HTTP Basic Auth for the API, so this will store the
        provided password, encrypted, for use in later API requests.
        """
        # This will raise an exception if it fails, which the form will
        # catch.
        self._api_get(self._build_api_url(unfuddle_account_domain, "account/"), username=username, password=password)

        self.account.data["password"] = encrypt_password(password)
        self.account.save()
示例#33
0
    def test_check_repository(self):
        """Testing that ReviewBoardGateway can find the repository"""
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(url, 'https://example.com/repos/myrepo/path')
            return '{}', {}

        account = self._get_hosting_account(use_url=True)
        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)
        account.data['private_token'] = encrypt_password('abc123')

        service.check_repository(path='https://example.com/repos/myrepo/path')
        self.assertTrue(service.client.http_get.called)
示例#34
0
    def test_check_repository_with_dot_git(self):
        """Testing Bitbucket check_repository with .git"""
        account = self._get_hosting_account()
        account.data['password'] = encrypt_password('abc123')
        service = account.service

        self.assertRaisesMessage(
            RepositoryError,
            'Please specify just the name of the repository without ".git".',
            lambda: service.check_repository(
                bitbucket_team_name='myteam',
                bitbucket_team_repo_name='myrepo.git',
                plan='team'))
示例#35
0
class ReviewBoardGatewayTestCase(HostingServiceTestCase):
    """Base test case for the ReviewBoardGateway hosting service."""

    service_name = 'rbgateway'

    default_use_hosting_url = True
    default_account_data = {
        'private_token': encrypt_password('abc123'),
    }

    default_repository_extra_data = {
        'rbgateway_repo_name': 'myrepo',
    }
示例#36
0
class GitLabTestCase(HostingServiceTestCase):
    """Base class for GitLab test suites."""

    service_name = 'gitlab'

    default_use_hosting_url = True
    default_account_data = {
        'private_token': encrypt_password('abc123'),
    }

    default_repository_extra_data = {
        'gitlab_project_id': 123456,
    }
示例#37
0
class BitbucketTestCase(HostingServiceTestCase):
    """Base class for Bitbucket test suites."""

    service_name = 'bitbucket'
    fixtures = ['test_scmtools']

    default_account_data = {
        'password': encrypt_password(HostingServiceTestCase.default_password),
    }

    default_repository_extra_data = {
        'bitbucket_repo_name': 'myrepo',
    }
    def test_check_repository(self):
        """Testing that ReviewBoardGateway can find the repository"""
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(url, 'https://example.com/repos/myrepo/path')
            return '{}', {}

        account = self._get_hosting_account(use_url=True)
        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)
        account.data['private_token'] = encrypt_password('abc123')

        service.check_repository(path='https://example.com/repos/myrepo/path')
        self.assertTrue(service.client.http_get.called)
示例#39
0
    def test_get_change(self):
        """Testing BitBucket get_change"""
        commit_sha = '1c44b461cebe5874a857c51a4a13a849a4d1e52d'
        parent_sha = '44568f7d33647d286691517e6325fea5c7a21d5e'

        commits_api_response = json.dumps({
            'hash': commit_sha,
            'author': {
                'raw': 'Some User <*****@*****.**>',
            },
            'date': '2017-01-24T13:11:22+00:00',
            'message': 'This is a message.',
            'parents': [{'hash': parent_sha}],
        })

        diff_api_response = b'This is a test \xc7.'
        norm_diff_api_response = b'This is a test \xc7.\n'

        def _http_get(service, url, *args, **kwargs):
            if url == ('https://bitbucket.org/api/2.0/repositories/'
                       'myuser/myrepo/commit/%s?'
                       'fields=author.raw%%2Chash%%2Cdate%%2C'
                       'message%%2Cparents.hash'
                       % commit_sha):
                return commits_api_response, None
            elif url == ('https://bitbucket.org/api/2.0/repositories/'
                         'myuser/myrepo/diff/%s' % commit_sha):
                return diff_api_response, None
            else:
                self.fail('Unexpected URL %s' % url)

        account = self._get_hosting_account()
        service = account.service
        repository = Repository(hosting_account=account,
                                tool=Tool.objects.get(name='Git'))
        repository.extra_data = {
            'bitbucket_repo_name': 'myrepo',
        }

        account.data['password'] = encrypt_password('abc123')

        self.spy_on(service.client.http_get, call_fake=_http_get)

        commit = service.get_change(repository, commit_sha)
        self.assertEqual(commit.id, commit_sha)
        self.assertEqual(commit.author_name, 'Some User <*****@*****.**>')
        self.assertEqual(commit.message, 'This is a message.')
        self.assertEqual(commit.date, '2017-01-24T13:11:22+00:00')
        self.assertEqual(commit.parent, parent_sha)
        self.assertEqual(commit.diff, norm_diff_api_response)
示例#40
0
    def _set_password(self, value):
        """Sets the password for the repository.

        The password will be stored as an encrypted value, prefixed with a
        tab character in order to differentiate between legacy plain-text
        passwords.
        """
        if value:
            value = '%s%s' % (self.ENCRYPTED_PASSWORD_PREFIX,
                              encrypt_password(value))
        else:
            value = ''

        self.encrypted_password = value
示例#41
0
    def _set_password(self, value):
        """Sets the password for the repository.

        The password will be stored as an encrypted value, prefixed with a
        tab character in order to differentiate between legacy plain-text
        passwords.
        """
        if value:
            value = '%s%s' % (self.ENCRYPTED_PASSWORD_PREFIX,
                              encrypt_password(value))
        else:
            value = ''

        self.encrypted_password = value
示例#42
0
    def authorize(self, username, password, *args, **kwargs):
        """Authorizes the Bitbucket repository.

        Bitbucket supports HTTP Basic Auth or OAuth for the API. We use
        HTTP Basic Auth for now, and we store provided password,
        encrypted, for use in later API requests.
        """
        self.account.data['password'] = encrypt_password(password)

        try:
            self._api_get(self._build_api_url('user'))
            self.account.save()
        except Exception:
            del self.account.data['password']
            raise
示例#43
0
    def authorize(self, username, password, *args, **kwargs):
        """Authorizes the Bitbucket repository.

        Bitbucket supports HTTP Basic Auth or OAuth for the API. We use
        HTTP Basic Auth for now, and we store provided password,
        encrypted, for use in later API requests.
        """
        self.account.data['password'] = encrypt_password(password)

        try:
            self._api_get(self._build_api_url('user'))
            self.account.save()
        except Exception:
            del self.account.data['password']
            raise
示例#44
0
    def test_get_commits(self):
        """Testing GitLab get_commits implementation"""
        commits_api_response = json.dumps([
            {
                'id': 'ed899a2f4b50b4370feeea94676502b42383c746',
                'author_name': 'Chester Li',
                'created_at': '2015-03-10T11:50:22+03:00',
                'message': 'Replace sanitize with escape once'
            },
            {
                'id': '6104942438c14ec7bd21c6cd5bd995272b3faff6',
                'author_name': 'Chester Li',
                'created_at': '2015-03-10T09:06:12+03:00',
                'message': 'Sanitize for network graph'
            },
            {
                'id': '21b3bcabcff2ab3dc3c9caa172f783aad602c0b0',
                'author_name': 'East Coast',
                'created_at': '2015-03-04T15:31:18.000-04:00',
                'message': 'Add a timer to test file'
            }
        ])

        def _http_get(self, *args, **kargs):
            return commits_api_response, None

        account = self._get_hosting_account(use_url=True)
        account.data['private_token'] = encrypt_password('abc123')

        service = account.service

        repository = Repository(hosting_account=account)
        repository.extra_data = {'gitlab_project_id': 123456}

        self.spy_on(service.client.http_get, call_fake=_http_get)

        commits = service.get_commits(
            repository, start='ed899a2f4b50b4370feeea94676502b42383c746')

        self.assertTrue(service.client.http_get.called)
        self.assertEqual(len(commits), 3)
        self.assertEqual(commits[0].id,
                         'ed899a2f4b50b4370feeea94676502b42383c746')
        self.assertNotEqual(commits[0].author_name, 'East Coast')
        self.assertEqual(commits[1].date, '2015-03-10T09:06:12+03:00')
        self.assertNotEqual(commits[1].message,
                            'Replace sanitize with escape once')
        self.assertEqual(commits[2].author_name, 'East Coast')
示例#45
0
    def test_personal_check_repository(self):
        """Testing Bitbucket personal check_repository"""
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(
                url,
                'https://bitbucket.org/api/1.0/repositories/myuser/myrepo')
            return b'{}', {}

        account = self._get_hosting_account()
        account.data['password'] = encrypt_password('abc123')
        service = account.service

        self.spy_on(service.client.http_get, call_fake=_http_get)

        service.check_repository(bitbucket_repo_name='myrepo', plan='personal')
        self.assertTrue(service.client.http_get.called)
    def test_personal_check_repository(self):
        """Testing Bitbucket personal check_repository"""
        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(
                url,
                'https://bitbucket.org/api/1.0/repositories/myuser/myrepo')
            return b'{}', {}

        account = self._get_hosting_account()
        account.data['password'] = encrypt_password('abc123')
        service = account.service

        self.spy_on(service.client.http_get, call_fake=_http_get)

        service.check_repository(bitbucket_repo_name='myrepo',
                                 plan='personal')
        self.assertTrue(service.client.http_get.called)
    def test_get_branches(self):
        """Testing ReviewBoardGateway get_branches implementation"""
        branches_api_response = json.dumps([
            {
                'name': 'master',
                'id': 'c272edcac05b00e15440d6274723b639e3acbd7c',
            },
            {
                'name': 'im_a_branch',
                'id': '83904e6acb60e7ec0dcaae6c09a579ab44d0cf38',
            }
        ])

        def _http_get(self, *args, **kwargs):
            return branches_api_response, None

        account = self._get_hosting_account()
        account.data['private_token'] = encrypt_password('abc123')

        repository = Repository(hosting_account=account)
        repository.extra_data = {
            'rbgateway_repo_name': 'myrepo',
        }

        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)

        branches = service.get_branches(repository)

        self.assertTrue(service.client.http_get.called)

        self.assertEqual(len(branches), 2)

        self.assertEqual(
            branches,
            [
                Branch(id='master',
                       commit='c272edcac05b00e15440d6274723b639e3acbd7c',
                       default=True),
                Branch(id='im_a_branch',
                       commit='83904e6acb60e7ec0dcaae6c09a579ab44d0cf38',
                       default=False)
            ])
示例#48
0
    def _test_check_repository(self, expected_user='******', **kwargs):
        def _http_get(service, url, *args, **kwargs):
            if url == 'https://example.com/api/v3/projects?per_page=100':
                payload = [
                    {
                        'id': 1,
                        'path': 'myrepo',
                        'namespace': {
                            'path': expected_user,
                        },
                    }
                ]
            elif url == 'https://example.com/api/v3/groups?per_page=100':
                payload = [
                    {
                        'id': 1,
                        'name': 'mygroup',
                    }
                ]
            elif url == 'https://example.com/api/v3/projects/1':
                # We don't care about the contents. Just that it exists.
                payload = {}
            elif url == 'https://example.com/api/v3/groups/1':
                payload = {
                    'projects': [
                        {
                            'id': 1,
                            'name': 'myrepo',
                        },
                    ],
                }
            else:
                self.fail('Unexpected URL %s' % url)

            return json.dumps(payload), {}

        account = self._get_hosting_account(use_url=True)
        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)
        account.data['private_token'] = encrypt_password('abc123')

        service.check_repository(**kwargs)
        self.assertTrue(service.client.http_get.called)
示例#49
0
    def test_check_repository_with_type_mismatch(self):
        """Testing Bitbucket check_repository with type mismatch"""
        error_message = (
            'The Bitbucket repository being configured does not match the '
            'type of repository you have selected.'
        )
        repository_type = 'git'

        def _http_get(service, url, *args, **kwargs):
            self.assertEqual(
                url,
                'https://bitbucket.org/api/2.0/repositories/myteam/myrepo'
                '?fields=scm')
            return (
                json.dumps({
                    'scm': repository_type,
                }),
                {})

        account = self._get_hosting_account()
        service = account.service
        account.data['password'] = encrypt_password('abc123')

        self.spy_on(service.client.http_get, call_fake=_http_get)

        # Check Git repositories.
        with self.assertRaisesMessage(RepositoryError, error_message):
            service.check_repository(
                bitbucket_team_name='myteam',
                bitbucket_team_repo_name='myrepo',
                plan='team',
                tool_name='Mercurial')

        # Now check Mercurial repositories.
        repository_type = 'hg'

        with self.assertRaisesMessage(RepositoryError, error_message):
            service.check_repository(
                bitbucket_team_name='myteam',
                bitbucket_team_repo_name='myrepo',
                plan='team',
                tool_name='Git')
    def test_get_change(self):
        """Testing ReviewBoardGateway get_change implementation"""
        diff = (b'diff --git a/test b/test\n'
                'index 9daeafb9864cf43055ae93beb0afd6c7d144bfa4..'
                'dced80a85fe1e8f13dd5ea19923e5d2e8680020d 100644\n'
                '--- a/test\n+++ b/test\n@@ -1 +1,3 @@\n test\n+\n+test\n')

        diff_encoding = md5(diff.encode('utf-8')).hexdigest()

        change_api_response = json.dumps(
            {
                'author': 'myname',
                'id': 'bfdde95432b3af879af969bd2377dc3e55ee46e6',
                'date': '2015-02-13 22:34:01 -0700 -0700',
                'message': 'mymessage',
                'parent_id': '304c53c163aedfd0c0e0933776f09c24b87f5944',
                'diff': diff
            }
        )

        def _http_get(self, *args, **kwargs):
            return change_api_response, None

        account = self._get_hosting_account()
        account.data['private_token'] = encrypt_password('abc123')

        repository = Repository(hosting_account=account)
        repository.extra_data = {
            'rbgateway_repo_name': 'myrepo',
        }

        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)

        change = service.get_change(
            repository, 'bfdde95432b3af879af969bd2377dc3e55ee46e6')

        self.assertTrue(service.client.http_get.called)

        self.assertEqual(change.message, 'mymessage')
        self.assertEqual(md5(change.diff.encode('utf-8')).hexdigest(),
                         diff_encoding)
示例#51
0
    def save(self):
        """Save the account page form.

        Stores an encrypted version of the API token.
        """
        api_token = self.cleaned_data['idonethis_api_token']
        settings = self.profile.settings.setdefault('idonethis', {})

        if api_token:
            logging.debug('IDoneThis: Saving API token for user "%s"',
                          self.user.username)
            settings['api_token'] = encrypt_password(api_token)
        elif 'api_token' in settings:
            logging.debug('IDoneThis: Deleting API token for user "%s"',
                          self.user.username)
            del settings['api_token']

        self.profile.save()

        delete_cached_user_team_ids(self.user)
示例#52
0
    def authorize(self, username, password, *args, **kwargs):
        """Authorizes the Bitbucket repository.

        Bitbucket supports HTTP Basic Auth or OAuth for the API. We use
        HTTP Basic Auth for now, and we store provided password,
        encrypted, for use in later API requests.
        """
        self.account.data['password'] = encrypt_password(password)

        try:
            self.api_get(self._build_api_url('user'))
            self.account.save()
        except HostingServiceError as e:
            del self.account.data['password']

            if e.http_code in (401, 403):
                self._raise_auth_error()
            else:
                raise
        except Exception:
            del self.account.data['password']
            raise
示例#53
0
    def authorize(self, username, password, *args, **kwargs):
        """Authorize the Assembla account.

        For Assembla, we simply use the native SCMTool support, as there's
        no useful API available. We just store the password encrypted, which
        will be used by the SCMTool.

        Args:
            username (unicode):
                The username for authentication.

            password (unicode):
                The password for authentication.

            *args (tuple):
                Additional arguments.

            **kwargs (dict):
                Additional keyword arguments.
        """
        self.account.data['password'] = encrypt_password(password)
        self.account.save()
示例#54
0
    def _test_check_repository_error(self, expected_error, **kwargs):
        def _http_get(service, url, *args, **kwargs):
            if url == 'https://example.com/api/v3/groups?per_page=100':
                payload = [
                    {
                        'id': 1,
                        'name': 'mygroup',
                    }
                ]
            elif url == 'https://example.com/api/v3/groups/1':
                payload = {
                    'projects': [
                        {
                            'id': 1,
                            'name': 'myrepo',
                        },
                    ],
                }
            else:
                payload = []

            return json.dumps(payload), {}

        account = self._get_hosting_account(use_url=True)
        service = account.service
        self.spy_on(service.client.http_get, call_fake=_http_get)
        account.data['private_token'] = encrypt_password('abc123')

        try:
            service.check_repository(**kwargs)
            saw_exception = False
        except Exception as e:
            self.assertEqual(six.text_type(e), expected_error)
            saw_exception = True

        self.assertTrue(saw_exception)