mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-25 11:01:09 +00:00
Provide hook to get registered credentials
This has to relax the session in getting and requesting validation.
This commit is contained in:
parent
9b39c96135
commit
c93f09bc91
@ -162,6 +162,8 @@ def authorize(name, element, tenant=False, operation='create',
|
||||
return False
|
||||
manager = configmanager.ConfigManager(tenant, username=user)
|
||||
userobj = manager.get_user(user)
|
||||
if element in ('/sessions/current/webauthn/registered_credentials', '/sessions/current/webauthn/validate'):
|
||||
return userobj, manager, user, tenant, skipuserobj
|
||||
if userobj and userobj.get('role', None) == 'Stub':
|
||||
userobj = None
|
||||
if not userobj:
|
||||
|
@ -211,6 +211,8 @@ def _should_skip_authlog(env):
|
||||
if '/sessions/current/async' in env['PATH_INFO']:
|
||||
# this is effectively invisible
|
||||
return True
|
||||
if '/sessions/current/webauthn/registered_credentials' in env['PATH_INFO']:
|
||||
return True
|
||||
if (env['REQUEST_METHOD'] == 'GET' and
|
||||
('/sensors/' in env['PATH_INFO'] or
|
||||
'/health/' in env['PATH_INFO'] or
|
||||
@ -274,11 +276,18 @@ def _authorize_request(env, operation):
|
||||
authdata = None
|
||||
name = ''
|
||||
sessionid = None
|
||||
sessid = None
|
||||
cookie = Cookie.SimpleCookie()
|
||||
element = env['PATH_INFO']
|
||||
if element.startswith('/sessions/current/'):
|
||||
element = None
|
||||
if 'HTTP_COOKIE' in env:
|
||||
if (element.startswith('/sessions/current/webauthn/registered_credentials/')
|
||||
or element.startswith('/sessions/current/webauthn/validate/')):
|
||||
username = element.rsplit('/')[-1]
|
||||
element = element.replace('/' + username, '')
|
||||
authdata = auth.authorize(name, element=element, operation=operation)
|
||||
else:
|
||||
element = None
|
||||
if (not authdata) and 'HTTP_COOKIE' in env:
|
||||
cidx = (env['HTTP_COOKIE']).find('confluentsessionid=')
|
||||
if cidx >= 0:
|
||||
sessionid = env['HTTP_COOKIE'][cidx+19:cidx+51]
|
||||
@ -356,11 +365,11 @@ def _authorize_request(env, operation):
|
||||
auditmsg['user'] = util.stringify(authdata[2])
|
||||
if sessid is not None:
|
||||
authinfo['sessionid'] = sessid
|
||||
if 'csrftoken' in httpsessions[sessid]:
|
||||
authinfo['authtoken'] = httpsessions[sessid]['csrftoken']
|
||||
httpsessions[sessid]['cfgmgr'] = authdata[1]
|
||||
if not skiplog:
|
||||
auditlog.log(auditmsg)
|
||||
if 'csrftoken' in httpsessions[sessid]:
|
||||
authinfo['authtoken'] = httpsessions[sessid]['csrftoken']
|
||||
httpsessions[sessid]['cfgmgr'] = authdata[1]
|
||||
return authinfo
|
||||
elif authdata is None:
|
||||
return {'code': 401}
|
||||
@ -636,7 +645,7 @@ def resourcehandler_backend(env, start_response):
|
||||
raise Exception("Unrecognized code from auth engine")
|
||||
headers.extend(
|
||||
("Set-Cookie", m.OutputString())
|
||||
for m in authorized['cookie'].values())
|
||||
for m in authorized.get('cookie', {}).values())
|
||||
cfgmgr = authorized['cfgmgr']
|
||||
if (operation == 'create') and env['PATH_INFO'] == '/sessions/current/async':
|
||||
pagecontent = ""
|
||||
@ -839,7 +848,7 @@ def resourcehandler_backend(env, start_response):
|
||||
start_response('501 Not Implemented', headers)
|
||||
yield ''
|
||||
return
|
||||
for rsp in webauthn.handle_api_request(url, env, start_response, authorized['username'], cfgmgr, headers):
|
||||
for rsp in webauthn.handle_api_request(url, env, start_response, authorized['username'], cfgmgr, headers, reqbody):
|
||||
yield rsp
|
||||
return
|
||||
resource = '.' + url[url.rindex('/'):]
|
||||
|
@ -1,3 +1,4 @@
|
||||
import base64
|
||||
import confluent.util as util
|
||||
import json
|
||||
import pywarp
|
||||
@ -11,9 +12,13 @@ class TestBackend(pywarp.backends.CredentialStorageBackend):
|
||||
pass
|
||||
|
||||
def get_credential_by_email(self, email):
|
||||
if not isinstance(email, str):
|
||||
email = email.decode('utf8')
|
||||
return creds[email]
|
||||
|
||||
def save_credential_for_user(self, email, credential):
|
||||
if not isinstance(email, str):
|
||||
email = email.decode('utf8')
|
||||
creds[email] = credential
|
||||
|
||||
def save_challenge_for_user(self, email, challenge, type):
|
||||
@ -23,15 +28,12 @@ class TestBackend(pywarp.backends.CredentialStorageBackend):
|
||||
return challenges[email]
|
||||
|
||||
|
||||
def handle_api_request(url, env, start_response, username, cfm, headers):
|
||||
def handle_api_request(url, env, start_response, username, cfm, headers, reqbody):
|
||||
if env['REQUEST_METHOD'] != 'POST':
|
||||
raise Exception('Only POST supported for webauthn operations')
|
||||
url = url.replace('/sessions/current/webauthn', '')
|
||||
if'CONTENT_LENGTH' in env and int(env['CONTENT_LENGTH']) > 0:
|
||||
reqbody = env['wsgi.input'].read(int(env['CONTENT_LENGTH']))
|
||||
reqtype = env['CONTENT_TYPE']
|
||||
if url == '/registration_options':
|
||||
rp = pywarp.RelyingPartyManager('Confluent Web UI', credential_storage_backend=TestBackend())
|
||||
rp = pywarp.RelyingPartyManager('Confluent Web UI', credential_storage_backend=TestBackend(), require_attestation=False)
|
||||
userinfo = cfm.get_user(username)
|
||||
if not userinfo:
|
||||
cfm.create_user(username, role='Stub')
|
||||
@ -47,5 +49,36 @@ def handle_api_request(url, env, start_response, username, cfm, headers):
|
||||
opts['user']['id'] = authid
|
||||
if 'icon' in opts['user']:
|
||||
del opts['user']['icon']
|
||||
if 'id' in opts['rp']:
|
||||
del opts['rp']['id']
|
||||
start_response('200 OK', headers)
|
||||
yield json.dumps(opts)
|
||||
elif url.startswith('/registered_credentials/'):
|
||||
username = url.rsplit('/', 1)[-1]
|
||||
rp = pywarp.RelyingPartyManager('Confluent Web UI', credential_storage_backend=TestBackend())
|
||||
if not isinstance(username, bytes):
|
||||
username = username.encode('utf8')
|
||||
opts = rp.get_authentication_options(username)
|
||||
opts['challenge'] = base64.b64encode(opts['challenge']).decode('utf8')
|
||||
start_response('200 OK', headers)
|
||||
yield json.dumps(opts)
|
||||
elif url == '/validate':
|
||||
rp = pywarp.RelyingPartyManager('Confluent Web UI', credential_storage_backend=TestBackend())
|
||||
req = json.loads(reqbody)
|
||||
for x in req:
|
||||
req[x] = base64.b64decode(req[x].replace('-', '+').replace('_', '/'))
|
||||
req['email'] = username
|
||||
rsp = rp.verify(**req)
|
||||
start_response('200 OK')
|
||||
yield json.dumps(rsp)
|
||||
elif url == '/register_credential':
|
||||
rp = pywarp.RelyingPartyManager('Confluent Web UI', credential_storage_backend=TestBackend(), require_attestation=False)
|
||||
req = json.loads(reqbody)
|
||||
for x in req:
|
||||
req[x] = base64.b64decode(req[x].replace('-', '+').replace('_', '/'))
|
||||
if not isinstance(username, bytes):
|
||||
username = username.encode('utf8')
|
||||
req['email'] = username
|
||||
rsp = rp.register(**req)
|
||||
start_response('200 OK', headers)
|
||||
yield json.dumps(rsp)
|
Loading…
Reference in New Issue
Block a user