Coverage for gws-app/gws/plugin/auth_method/basic/__init__.py: 0%
49 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-17 01:37 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-17 01:37 +0200
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.register_middleware(self.uid, depends_on=['auth'])
29 ##
31 def enter_middleware(self, req):
32 pass
34 def exit_middleware(self, req, res):
35 if res.status == 403 and req.isGet:
36 res.set_status(401)
37 res.add_header('WWW-Authenticate', f'Basic realm={self.realm}, charset="UTF-8"')
39 def open_session(self, req):
40 am = self.root.app.authMgr
41 credentials = self._parse_header(req)
42 if not credentials:
43 return
44 user = am.authenticate(self, credentials)
45 if user:
46 return am.sessionMgr.create(self, user)
48 def close_session(self, req, res):
49 pass
51 def _parse_header(self, req: gws.WebRequester):
52 h = req.header('Authorization')
53 if not h:
54 return
56 a = h.strip().split()
57 if len(a) != 2 or a[0].lower() != 'basic':
58 return
60 try:
61 b = gws.u.to_str(base64.decodebytes(gws.u.to_bytes(a[1])))
62 except ValueError:
63 return
65 c = b.split(':')
66 if len(c) != 2:
67 return
69 username = c[0].strip()
70 if not username:
71 return
73 return gws.Data(username=username, password=c[1])