generated from jric11/baseProject
ChatGPT's update to harden software and run db updates.
This commit is contained in:
@@ -20,7 +20,8 @@ class Application:
|
||||
if not os.environ.get('HCR_TEST_DSN'):
|
||||
raise RuntimeError('An isolated HCR_TEST_DSN is required.')
|
||||
self.env=os.environ.copy()
|
||||
self.env.update(HCR_APPLICATION_URL='',HCR_ENVIRONMENT='Development')
|
||||
self.env['HCR_MFA_KEY']='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
|
||||
self.env.update(HCR_SUPER_ADMIN_EMAIL='',HCR_APPLICATION_URL='',HCR_ENVIRONMENT='Development',HCR_SMTP_HOST='127.0.0.1',HCR_SMTP_PORT='1',HCR_SMTP_USER='test@example.test',HCR_SMTP_PASSWORD='test-only',HCR_SMTP_FROM='test@example.test')
|
||||
self.database=self.fixture('create')['database']
|
||||
self.env['HCR_DB_NAME']=self.database
|
||||
with socket.socket() as available:
|
||||
@@ -52,7 +53,27 @@ class Application:
|
||||
_,body,_=self.request()
|
||||
status,body,_=self.request(data={'action':'SignIn.login','csrf_token':self.csrf(body),'user_email':email,'user_password':password})
|
||||
if status!=200 or b'name="csrf-token"' not in body:raise AssertionError('Login failed: '+body[:500].decode(errors='replace'))
|
||||
if b'<h1>Account security</h1>' in body:
|
||||
if b'setup key' in body:
|
||||
secret=re.search(rb'<pre>([A-Z2-7]+)</pre>',body).group(1).decode()
|
||||
code=self.totp(secret)
|
||||
status,body,_=self.request(data={'action':'security','csrf_token':self.csrf(body),'current_password':password,'mfa_code':code})
|
||||
if b'Save your recovery codes' not in body:raise AssertionError(body[:1000])
|
||||
recovery=re.findall(rb'\b[a-f0-9]{32}\b',body)
|
||||
self.recovery=[c.decode() for c in recovery]
|
||||
status,body,_=self.request()
|
||||
else:
|
||||
code=self.fixture('mfaCode',email)['code']
|
||||
status,body,_=self.request(data={'action':'security','csrf_token':self.csrf(body),'current_password':password,'mfa_code':code})
|
||||
if status!=200:raise AssertionError('MFA failed: '+str(status))
|
||||
self.token=self.csrf(body)
|
||||
@staticmethod
|
||||
def totp(secret, at=None):
|
||||
import base64,hashlib,hmac,struct,time
|
||||
secret=base64.b32decode(secret+'='*((8-len(secret)%8)%8))
|
||||
digest=hmac.new(secret,struct.pack('>Q',int((time.time() if at is None else at)//30)),hashlib.sha1).digest()
|
||||
offset=digest[-1]&15
|
||||
return str((int.from_bytes(digest[offset:offset+4],'big')&0x7fffffff)%1000000).zfill(6)
|
||||
def post(self,action,**values):
|
||||
return self.request(data={'action':action,'csrf_token':self.token,**values},ajax=True)
|
||||
def logout(self):self.post('signout')
|
||||
|
||||
Reference in New Issue
Block a user