def authenticate(self): """ Ask VCCS credential backend to authenticate a credential. :rtype: bool """ self._status = False self._logger.debug("Authenticating token of type {!r}".format( self._request.token_type)) client = vccs_client.VCCSClient(base_url=self._config.vccs_base_url) user_code = self._request.token.user_code if self._request.token_type == 'OATH': assert isinstance(self._user.factors, eduid_api.authfactor.EduIDAuthFactorList) oath_factors = [] for factor in self._user.factors.to_list(): assert isinstance(factor, eduid_api.authfactor.EduIDAuthFactor ) # for pycharm type inference if factor.type in ['oath-hotp', 'oath-totp']: this = vccs_client.VCCSOathFactor(factor.type, credential_id=factor.id, user_code=user_code) oath_factors.append(this) self._logger.debug( "Calling VCCS client at {!r} to authenticate factor(s) {!r}". format(self._config.vccs_base_url, oath_factors)) if client.authenticate(self._user.user_id, oath_factors): self._status = True return True else: raise NotImplemented() return False
def generate_password(credential_id, user): """ Generate a new password credential and add it to the VCCS authentication backend. The salt returned needs to be saved for use in subsequent authentications using this password. The password is returned so that it can be conveyed to the user. :param credential_id: VCCS credential_id as string :param user: user data as dict :return: (password, salt) both strings """ user_id = str(user.user_id) config = current_app.config password = pwgen(int(config.get('PASSWORD_LENGTH')), no_capitalize=True, no_symbols=True) factor = vccs_client.VCCSPasswordFactor(password, credential_id) current_app.logger.info("Adding VCCS password factor for user {}, " "credential_id {!r}".format(user, credential_id)) vccs = vccs_client.VCCSClient(base_url=config.get('VCCS_URL')) try: result = vccs.add_credentials(user_id, [factor]) except vccs_client.VCCSClientHTTPError as e: current_app.logger.error( 'There was an error adding credentials for user {} ' ': {!r}'.format(user, e)) raise e current_app.logger.debug("VCCS password (id {!r}) creation result: " "{!r}".format(credential_id, result)) return _human_readable(password), factor.salt
def add_to_authbackend(self): """ Ask VCCS credential backend to store a new credential. """ self._logger.debug("Adding token of type {!r} to authbackend".format( self._request.token_type)) if self._request.token_type == 'OATH': self._get_oath_aead() # dump all attributes on self to logger #for attr in dir(self): # self._logger.debug("ATTR {!r}: {!r}".format(attr, getattr(self, attr))) token_type = 'oath-{!s}'.format(self._request.token.type) self._factor = vccs_client.VCCSOathFactor( token_type, self._token_id, nonce=self.aead.nonce, aead=self.aead.aead, key_handle=self.aead.key_handle, digits=self._request.token.digits, oath_counter=self._request.token.initial_counter, ) else: raise NotImplemented() client = vccs_client.VCCSClient(base_url=self._config.vccs_base_url) self._logger.debug("Extra debug: Adding credential {!r}".format( self._factor.credential_id)) client.add_credentials(str(self._user_id), [self._factor]) self._status = True
def get_vccs_client(vccs_url): """ Instantiate a VCCS client. :param vccs_url: VCCS authentication backend URL :type vccs_url: string :return: vccs client :rtype: VCCSClient """ return vccs_client.VCCSClient(base_url=vccs_url, )