Coverage for gws-app / gws / plugin / auth_method / basic / __init__.py: 40%
48 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-03 10:12 +0100
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-03 10:12 +0100
1"""HTTP Basic authorisation method."""
3from typing import Optional
5import base64
7import gws
8import gws.base.auth
9import gws.base.web
11gws.ext.new.authMethod('basic')
14class Config(gws.base.auth.method.Config):
15 """HTTP-basic authorization options"""
17 realm: Optional[str]
18 """Authentication realm."""
21class Object(gws.base.auth.method.Object):
22 realm: str
24 def configure(self):
25 self.uid = 'gws.plugin.auth_method.basic'
26 self.realm = self.cfg('realm', default='Restricted Area')
27 self.root.app.middlewareMgr.register(self, self.uid, depends_on=['auth'])
29 ##
31 def exit_middleware(self, req, res):
32 if res.status == 403 and req.isGet:
33 res.set_status(401)
34 res.add_header('WWW-Authenticate', f'Basic realm={self.realm}, charset="UTF-8"')
35 gws.log.debug(f'auth basic: redirect {res.status=}')
38 def open_session(self, req):
39 am = self.root.app.authMgr
40 credentials = self._parse_header(req)
41 if not credentials:
42 return
43 user = am.authenticate(self, credentials)
44 if user:
45 return am.sessionMgr.create(self, user)
47 def close_session(self, req, res):
48 pass
50 def _parse_header(self, req: gws.WebRequester):
51 h = req.header('Authorization')
52 if not h:
53 return
55 a = h.strip().split()
56 if len(a) != 2 or a[0].lower() != 'basic':
57 return
59 try:
60 b = gws.u.to_str(base64.decodebytes(gws.u.to_bytes(a[1])))
61 except ValueError:
62 return
64 c = b.split(':')
65 if len(c) != 2:
66 return
68 username = c[0].strip()
69 if not username:
70 return
72 return gws.Data(username=username, password=c[1])