[docs]classHOTP(OTP):""" Handler for HMAC-based OTP counters. """def__init__(self,s:str,digits:int=6,digest:Any=None,name:Optional[str]=None,issuer:Optional[str]=None,initial_count:int=0,)->None:""" :param s: secret in base32 format :param initial_count: starting HMAC counter value, defaults to 0 :param digits: number of integers in the OTP. Some apps expect this to be 6 digits, others support more. :param digest: digest function to use in the HMAC (expected to be SHA1) :param name: account name :param issuer: issuer """ifdigestisNone:digest=hashlib.sha1self.initial_count=initial_countsuper().__init__(s=s,digits=digits,digest=digest,name=name,issuer=issuer)
[docs]defat(self,count:int)->str:""" Generates the OTP for the given count. :param count: the OTP HMAC counter :returns: OTP """returnself.generate_otp(self.initial_count+count)
[docs]defverify(self,otp:str,counter:int)->bool:""" Verifies the OTP passed in against the current counter OTP. :param otp: the OTP to check against :param counter: the OTP HMAC counter """returnutils.strings_equal(str(otp),str(self.at(counter)))
[docs]defprovisioning_uri(self,name:Optional[str]=None,initial_count:Optional[int]=None,issuer_name:Optional[str]=None,**kwargs,)->str:""" Returns the provisioning URI for the OTP. This can then be encoded in a QR Code and used to provision an OTP app like Google Authenticator. See also: https://github.com/google/google-authenticator/wiki/Key-Uri-Format :param name: name of the user account :param initial_count: starting HMAC counter value, defaults to 0 :param issuer_name: the name of the OTP issuer; this will be the organization title of the OTP entry in Authenticator :returns: provisioning URI """returnutils.build_uri(self.secret,name=nameifnameelseself.name,initial_count=initial_countifinitial_countelseself.initial_count,issuer=issuer_nameifissuer_nameelseself.issuer,algorithm=self.digest().name,digits=self.digits,**kwargs,)