def save(self, allow_authorize=True, force_authorize=False, extra_authorize_kwargs=None, trust_host=False, save=True): """Save the hosting account and authorize against the service. This will create or update a hosting account, based on the information provided in the form and to this method. :py:meth:`is_valid` must be called prior to saving. Args: allow_authorize (bool, optional): If ``True`` (the default), the account will be authorized against the hosting service. If ``False``, only the database entry for the account will be affected. force_authorize (bool, optional): Force the account to be re-authorized, if already authorized. extra_authorize_kwargs (dict, optional): Additional keyword arguments to provide for the :py:meth:`HostingService.authorize() <reviewboard.hostingsvcs.models.HostingService.authorize>` call. trust_host (bool, optional): Whether to trust the given host, even if the linked certificate is invalid or self-signed. save (bool, optional): Whether or not the created account should be saved. This is intended to be used by subclasses who want to add additional data to the resulting hosting account before saving. If this is ``False``, the caller must ensure the resulting hosting account is saved. Returns: reviewboard.hostingsvcs.models.HostingServiceAccount: The updated or created hosting service account. Raises: reviewboard.hostingsvcs.errors.AuthorizationError: Information needed to authorize was missing, or authorization failed. reviewboard.hostingsvcs.errors.TwoFactorAuthCodeRequiredError: A two-factor authentication code is required to authorize the account. A code will need to be provided to the form. """ if extra_authorize_kwargs is None: extra_authorize_kwargs = {} credentials = self.get_credentials() # Grab the username from the credentials, sanity-checking that it's # been provided as part of the get_credentials() result. try: username = credentials['username'] except KeyError: logging.exception( '%s.get_credentials() must return a "username" ' 'key.', self.__class__.__name__) raise AuthorizationError( ugettext('Hosting service implementation error: ' '%s.get_credentials() must return a "username" key.') % self.__class__.__name__) hosting_account = self.hosting_account hosting_service_id = self.hosting_service_cls.hosting_service_id hosting_url = self.cleaned_data.get('hosting_url') if not self.hosting_service_cls.self_hosted: assert hosting_url is None if hosting_account: # Update the username and hosting URL, if they've changed. hosting_account.username = username hosting_account.hosting_url = hosting_url else: # Fetch an existing hosting account based on the credentials and # parameters, if there is one. If not, we're going to create one, # but we won't save it until we've authorized. hosting_account_attrs = { 'service_name': hosting_service_id, 'username': username, 'hosting_url': hosting_url, 'local_site': self.local_site, } try: hosting_account = \ HostingServiceAccount.objects.get(**hosting_account_attrs) except HostingServiceAccount.DoesNotExist: # Create a new one, but don't save it yet. hosting_account = \ HostingServiceAccount(**hosting_account_attrs) if (allow_authorize and self.hosting_service_cls.needs_authorization and (not hosting_account.is_authorized or force_authorize)): # Attempt to authorize the account. if self.local_site: local_site_name = self.local_site.name else: local_site_name = None password = credentials.get('password') two_factor_auth_code = credentials.get('two_factor_auth_code') authorize_kwargs = dict( { 'username': username, 'password': password, 'hosting_url': hosting_url, 'two_factor_auth_code': two_factor_auth_code, 'local_site_name': local_site_name, 'credentials': credentials, }, **extra_authorize_kwargs) try: self.authorize(hosting_account, hosting_service_id, **authorize_kwargs) except UnverifiedCertificateError as e: if trust_host: hosting_account.accept_certificate(e.certificate) self.authorize(hosting_account, hosting_service_id, **authorize_kwargs) else: raise if save: hosting_account.save() return hosting_account
def save(self, allow_authorize=True, force_authorize=False, extra_authorize_kwargs=None, trust_host=False, save=True): """Save the hosting account and authorize against the service. This will create or update a hosting account, based on the information provided in the form and to this method. :py:meth:`is_valid` must be called prior to saving. Args: allow_authorize (bool, optional): If ``True`` (the default), the account will be authorized against the hosting service. If ``False``, only the database entry for the account will be affected. force_authorize (bool, optional): Force the account to be re-authorized, if already authorized. extra_authorize_kwargs (dict, optional): Additional keyword arguments to provide for the :py:meth:`HostingService.authorize() <reviewboard.hostingsvcs.models.HostingService.authorize>` call. trust_host (bool, optional): Whether to trust the given host, even if the linked certificate is invalid or self-signed. save (bool, optional): Whether or not the created account should be saved. This is intended to be used by subclasses who want to add additional data to the resulting hosting account before saving. If this is ``False``, the caller must ensure the resulting hosting account is saved. Returns: reviewboard.hostingsvcs.models.HostingServiceAccount: The updated or created hosting service account. Raises: reviewboard.hostingsvcs.errors.AuthorizationError: Information needed to authorize was missing, or authorization failed. reviewboard.hostingsvcs.errors.TwoFactorAuthCodeRequiredError: A two-factor authentication code is required to authorize the account. A code will need to be provided to the form. """ if extra_authorize_kwargs is None: extra_authorize_kwargs = {} credentials = self.get_credentials() # Grab the username from the credentials, sanity-checking that it's # been provided as part of the get_credentials() result. try: username = credentials['username'] except KeyError: logging.exception('%s.get_credentials() must return a "username" ' 'key.', self.__class__.__name__) raise AuthorizationError( ugettext('Hosting service implementation error: ' '%s.get_credentials() must return a "username" key.') % self.__class__.__name__) hosting_account = self.hosting_account hosting_service_id = self.hosting_service_cls.hosting_service_id hosting_url = self.cleaned_data.get('hosting_url') if not self.hosting_service_cls.self_hosted: assert hosting_url is None if hosting_account: # Update the username and hosting URL, if they've changed. hosting_account.username = username hosting_account.hosting_url = hosting_url else: # Fetch an existing hosting account based on the credentials and # parameters, if there is one. If not, we're going to create one, # but we won't save it until we've authorized. hosting_account_attrs = { 'service_name': hosting_service_id, 'username': username, 'hosting_url': hosting_url, 'local_site': self.local_site, } try: hosting_account = \ HostingServiceAccount.objects.get(**hosting_account_attrs) except HostingServiceAccount.DoesNotExist: # Create a new one, but don't save it yet. hosting_account = \ HostingServiceAccount(**hosting_account_attrs) if (allow_authorize and self.hosting_service_cls.needs_authorization and (not hosting_account.is_authorized or force_authorize)): # Attempt to authorize the account. if self.local_site: local_site_name = self.local_site.name else: local_site_name = None password = credentials.get('password') two_factor_auth_code = credentials.get('two_factor_auth_code') authorize_kwargs = dict({ 'username': username, 'password': password, 'hosting_url': hosting_url, 'two_factor_auth_code': two_factor_auth_code, 'local_site_name': local_site_name, 'credentials': credentials, }, **extra_authorize_kwargs) try: self.authorize(hosting_account, hosting_service_id, **authorize_kwargs) except UnverifiedCertificateError as e: if trust_host: hosting_account.accept_certificate(e.certificate) self.authorize(hosting_account, hosting_service_id, **authorize_kwargs) else: raise if save: hosting_account.save() return hosting_account