Nexom 1.0.4__py3-none-any.whl → 1.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
nexom/templates/auth.py CHANGED
@@ -2,13 +2,16 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from importlib import resources
5
+ import pathlib as plb
5
6
 
6
- from ..app.auth import AuthClient
7
+ from ..app.auth import AuthClient, KEY_NAME
7
8
  from ..app.request import Request
8
- from ..app.response import HtmlResponse, JsonResponse
9
+ from ..app.response import HtmlResponse, JsonResponse, Redirect, ErrorResponse
10
+ from ..app.cookie import Cookie
11
+ from ..app.path import Path, Router
9
12
  from ..core.object_html_render import HTMLDoc, ObjectHTML
13
+ from ..core.error import NexomError, _status_for_auth_error
10
14
 
11
- from ..core.error import NexomError
12
15
 
13
16
  # --------------------
14
17
  # Object HTML
@@ -30,43 +33,106 @@ _OHTML: ObjectHTML = ObjectHTML(
30
33
  # Pages
31
34
  # --------------------
32
35
 
33
- class LoginPage:
34
- def __init__(self, auth_server: str) -> None:
36
+ class AuthPages(Path):
37
+ def __init__(self,
38
+ path: str,
39
+ auth_server: str,
40
+ *,
41
+ login_path: str = "login/",
42
+ signup_path: str = "signup/",
43
+ logout_path: str = "logout/"
44
+ ):
45
+ self.auth_server = auth_server
46
+
47
+ root = plb.Path(path)
48
+ self.routing = Router(
49
+ LoginPage(str(root / login_path), self.auth_server),
50
+ SignupPage(str(root / signup_path), self.auth_server),
51
+ LogoutPage(str(root / logout_path), self.auth_server),
52
+ )
53
+
54
+ super().__init__(path, self._handler, "UserAuthPage")
55
+
56
+ def _handler(self, req: Request, args: dict) -> JsonResponse:
57
+
58
+ p = self.routing.get(req.path)
59
+ return p.call_handler(req)
60
+
61
+
62
+ class LoginPage(Path):
63
+ def __init__(self, path: str, auth_server: str) -> None:
64
+ super().__init__(path, self._handler, "LoginPage")
65
+
35
66
  self.client = AuthClient(auth_server)
36
67
 
37
- def page(self, req: Request, args: dict) -> HtmlResponse | JsonResponse:
68
+ def _handler(self, req: Request, args: dict) -> JsonResponse:
38
69
  if req.method == "GET":
39
- return HtmlResponse(_OHTML.render("login"))
70
+ return HtmlResponse(_OHTML.render("login", page_path=req.path))
40
71
 
41
72
  try:
42
73
  data = req.json() or {}
43
74
  token, user_id, exp = self.client.login(
44
- user_id=data.get("user_id", ""),
45
- password=data.get("password", ""),
75
+ user_id=str(data.get("user_id") or ""),
76
+ password=str(data.get("password") or ""),
46
77
  )
47
- return JsonResponse({"ok": True, "user_id": user_id, "token": token, "expires_at": exp})
78
+
79
+ set_cookie = Cookie(KEY_NAME, token, Path="/", MaxAge=exp)
80
+ return JsonResponse({"ok": True, "user_id": user_id, "token": token, "expires_at": exp}, cookie=str(set_cookie))
48
81
  except NexomError as e:
49
- return JsonResponse({"error": e.code}, status=401)
82
+ return JsonResponse({"ok": False, "error": e.code}, status=_status_for_auth_error(e.code))
83
+
50
84
  except Exception:
51
- return JsonResponse({"error": "Internal Server Error"}, status=401)
85
+ return JsonResponse({"ok": False, "error": "InternalError"}, status=500)
86
+
87
+ class SignupPage(Path):
88
+ def __init__(self, path: str, auth_server: str) -> None:
89
+ super().__init__(path, self._handler, "SignupPage")
52
90
 
53
- class SignupPage:
54
- def __init__(self, auth_server: str) -> None:
55
91
  self.client = AuthClient(auth_server)
56
92
 
57
- def page(self, req: Request, args: dict) -> HtmlResponse | JsonResponse:
93
+ def _handler(self, req: Request, args: dict) -> JsonResponse:
58
94
  if req.method == "GET":
59
- return HtmlResponse(_OHTML.render("signup"))
95
+ return HtmlResponse(_OHTML.render("signup", page_path=req.path))
60
96
 
61
97
  try:
62
98
  data = req.json() or {}
63
- ok = self.client.signup(
64
- user_id=data.get("user_id", ""),
65
- public_name=data.get("public_name", ""),
66
- password=data.get("password", ""),
99
+ self.client.signup(
100
+ user_id=str(data.get("user_id") or ""),
101
+ public_name=str(data.get("public_name") or ""),
102
+ password=str(data.get("password") or ""),
67
103
  )
68
- return JsonResponse({"ok": ok})
104
+ return JsonResponse({"ok": True}, status=201)
105
+
69
106
  except NexomError as e:
70
- return JsonResponse({"error": e.code}, status=401)
107
+ return JsonResponse({"ok": False, "error": e.code}, status=_status_for_auth_error(e.code))
108
+
71
109
  except Exception:
72
- return JsonResponse({"error": "Internal Server Error"}, status=401)
110
+ return JsonResponse({"ok": False, "error": "InternalError"}, status=500)
111
+
112
+
113
+ class LogoutPage(Path):
114
+ def __init__(self, path: str, auth_server: str) -> None:
115
+ super().__init__(path, self._handler, "LogoutPage")
116
+ self.client = AuthClient(auth_server)
117
+
118
+ def _handler(self, req: Request, args: dict) -> Redirect | ErrorResponse:
119
+ if req.method != "GET":
120
+ return ErrorResponse(405, "Please make a GET request")
121
+
122
+ token = req.cookie.get(KEY_NAME) if req.cookie else None
123
+
124
+ redirect_url = req.headers.get("referer") or "/"
125
+ if not redirect_url.startswith("/"):
126
+ redirect_url = "/"
127
+
128
+ if token:
129
+ try:
130
+ self.client.logout(token=token)
131
+ except NexomError as e:
132
+ return ErrorResponse(500, e.code)
133
+ except Exception as e:
134
+ return ErrorResponse(500, str(e))
135
+
136
+ set_cookie = Cookie(KEY_NAME, "", Path="/", MaxAge=0)
137
+ return Redirect(redirect_url, cookie=str(set_cookie))
138
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Nexom
3
- Version: 1.0.4
3
+ Version: 1.0.5
4
4
  Summary: Lightweight Python Web Framework (WSGI)
5
5
  Author: TouriAida
6
6
  License: MIT License
@@ -191,4 +191,4 @@ sudo systemd start banana-project@banana2
191
191
  sudo systemd start banana-project@banana3
192
192
  ```
193
193
 
194
- 2026 1/25
194
+ 2026 1/27
@@ -1,56 +1,57 @@
1
1
  nexom/__init__.py,sha256=V6US1i4gO-EOWsoHEgxzwbkrLPnzPhSn6TYue3uVsBA,367
2
2
  nexom/__main__.py,sha256=VKT7WSe6552_mzwLwJqa55tfag5Olr28eYVhVnf9kWY,6196
3
- nexom/app/__init__.py,sha256=meq2MgHUNgcjVn4V3dzm52EIlrGeIdNS-09sGLhita4,1090
4
- nexom/app/auth.py,sha256=iwaFIXjiwjkVFRGtDFUoQ2dK9aUeP-uxQF5xwd4vCTE,10020
3
+ nexom/app/__init__.py,sha256=DgKTx8GtuRJkiRwBKmLhCLlf3l19zTWwXEmeRPznzlM,1089
4
+ nexom/app/auth.py,sha256=vpu_rb35s4z9CZK3tNvgNFHiD8KFv8zs3uUsOHFyZD0,13209
5
5
  nexom/app/cookie.py,sha256=VCau9i8z6QlkaE_s8gKZXjcFtrV2bX1T4xssNtpJ5A0,2026
6
- nexom/app/db.py,sha256=gUJOlUJqDaHCYU5JkzGV_wf_OTvFlqDWvM7vJDNVulY,2816
6
+ nexom/app/db.py,sha256=fl3SrNPOltTT3d5PqjISdS4u7SXEMRqLPotbJE0FXsY,3320
7
7
  nexom/app/http_status_codes.py,sha256=R4ka3n4rijqvfahF5n5kS-Qrg8bZSsrvF8lGnpKWAgY,1934
8
8
  nexom/app/middleware.py,sha256=7bHGtEem92QhgULOvTFDFlZ4K719CQgu9RKj1g7XOW8,1429
9
- nexom/app/path.py,sha256=o7HUr_p4oRLhXo7YAD8jqgXVkrrRW6KUoY2unAI7s1Y,6007
9
+ nexom/app/path.py,sha256=k6Kzwf1xRHNPgqxwLwFQMAO3VqsGZNQ8RzjRfVKtCH0,6006
10
10
  nexom/app/request.py,sha256=4dvcfrrS9gKzVFtoizRw5eFvP7eHRXsavh21zEHXX2U,8867
11
- nexom/app/response.py,sha256=qmLm8wCcexLjUIj8DaOBxt0cK3_J4Rn6DuWn6wkE7cE,4299
12
- nexom/app/template.py,sha256=4V4YSaZ92Gq76lj6HgPaF7obvvzmM42Gh8f0e5oAIzM,3587
11
+ nexom/app/response.py,sha256=a5297XDlDkoArymss-oxLTJ1a0I-MNjFUvFel0CQnN8,4483
12
+ nexom/app/template.py,sha256=sGaO39EPrPs-K_4gUxdhtEOyjzYyEPTUzpBzJqFP-_Y,3650
13
13
  nexom/app/user.py,sha256=6KLLsb08Ma39CnLBbq5y290o33tfxtHFWu9lu1kT0NM,623
14
14
  nexom/assets/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  nexom/assets/app/config.py,sha256=Ltpj40PE1--s0eRPTHiJNFqG8pFA7Lb6x02C39kwoYA,765
16
16
  nexom/assets/app/gunicorn.conf.py,sha256=0kAQ7ddfpnPpqLAZxIXqYPF6EuUzkjIC9aOTqfxn6rc,149
17
- nexom/assets/app/router.py,sha256=6VplXBlyvdsN144zy165sA3NZuvguMy6oO-mR0ebM2U,320
17
+ nexom/assets/app/router.py,sha256=_agfa_NFOxpCzGkCzDZIR0x5EkTn4wyg_ROBUiZouGU,318
18
18
  nexom/assets/app/wsgi.py,sha256=o-GtCPPHKiavTOmr8qxqCY95iUFU_IvRmwLqLK3ecwU,1743
19
- nexom/assets/app/__pycache__/__init__.cpython-313.pyc,sha256=4WFkUYDuBZdpaXyXHrp3g5nTjc1XtExGRIyTPUyCFGM,195
19
+ nexom/assets/app/__pycache__/__init__.cpython-313.pyc,sha256=5qiNgiTI26RZcyxr09EKigB5YYYBSqRJxyq8LCVWR14,195
20
20
  nexom/assets/app/pages/__init__.py,sha256=DlX9iwM39JaMKfzK4mbgjE2uVMX3ax0wd2mCVnpg0b4,61
21
- nexom/assets/app/pages/_templates.py,sha256=3lz42xOzHodOhFnujMhOuMX6IBJjMXGQKmOZ8SVhgE4,190
21
+ nexom/assets/app/pages/_templates.py,sha256=1c8KUwfMHkoo7S4neFbYjs5ixK44evn-uFVAFR9Y834,213
22
22
  nexom/assets/app/pages/default.py,sha256=Kmm8ud8Uh1BAIba28Zp3Wz6WsTTx7cQ6-t6RMkuL9qU,257
23
23
  nexom/assets/app/pages/document.py,sha256=JI9ChJ2BTXFyOiCnm4PRUnOY1xaLHeOI1ZEqHMQ7zPI,245
24
- nexom/assets/app/pages/__pycache__/__init__.cpython-313.pyc,sha256=p0AGZjUdMtwO8e3cnmA3_R0rz1G5UFZNvVNICSHK8g0,273
24
+ nexom/assets/app/pages/__pycache__/__init__.cpython-313.pyc,sha256=iQGBtjKUOXVUrrp1qQIfoj44NL_I2H_YGdL-RJ7gtC8,273
25
25
  nexom/assets/app/static/dog.jpeg,sha256=qGEhcg48FxRLRISzbmXvw1qvfbdluC_ukM8ZrHg7_XE,6559
26
- nexom/assets/app/static/style.css,sha256=mDKNWue0uRLdWB0w1RsMSn6h3tHsuTVLuk3xOOJl7X8,566
26
+ nexom/assets/app/static/github.png,sha256=DUwjX--e_sVBdKfABfwP4M4tY9NcIYmKtRSFhxETl6k,6223
27
+ nexom/assets/app/static/style.css,sha256=vPDDlaWkw3Qow1yF8lSmXMTIzAQU5VrVqfoTijj6AH0,11883
27
28
  nexom/assets/app/templates/base.html,sha256=RVW_63gA1sr7pqNkfB6Djk5an_VFpowahDIHGjfV-Wk,349
28
- nexom/assets/app/templates/default.html,sha256=EKG9NTYkXngdCiDodSI1Kuic_ZwVwdeRc3VLq6fX5UI,167
29
- nexom/assets/app/templates/document.html,sha256=16ClimpeqhLnXFNa8nMdMOlXUu8JOw7XxfpjU9DdIFs,6243
30
- nexom/assets/app/templates/footer.html,sha256=1NZbbarU-CQhs1OPs2MTzhnWu0h7YYiEKDIP_cgIl9I,98
31
- nexom/assets/app/templates/header.html,sha256=VgkCtCVE1J-eGEYvbBgWSUU-QauEf6xuvweOE-84U9c,75
29
+ nexom/assets/app/templates/default.html,sha256=JTNSlSkRAXPLNoQd2ZlVwyvZ-Ypi0IFZphkYQfsWo1E,311
30
+ nexom/assets/app/templates/document.html,sha256=QocJuK2CHl9NxGLbuQKmMICDwaV9Na_0ZGxluwmaorI,5706
31
+ nexom/assets/app/templates/footer.html,sha256=mh0mm4f1nHIGV3cjDFFi8gpYwEpgk5Jqpbjokh9DPbA,94
32
+ nexom/assets/app/templates/header.html,sha256=BQ4p0GOsx4WxusyjUNfdq1Lk1qlcmCoaYtgI288F5IE,345
32
33
  nexom/assets/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
34
  nexom/assets/auth/config.py,sha256=YgwEDhTsaxOxaOhUVSw6meay8Nc50A3GXafzmSdnhWo,804
34
35
  nexom/assets/auth/gunicorn.conf.py,sha256=PbCWHG-A2OCfL71G04XS9xr78aH_gg-1UpH2tJhTWUk,141
35
36
  nexom/assets/auth/wsgi.py,sha256=sMTj_ei0w1skoR_-xBNpveGAhRKWANfd1UaAItXQFO8,1698
36
- nexom/assets/auth/__pycache__/__init__.cpython-313.pyc,sha256=dRCVl1pZMRjC5NpwgaW4uanJl9l4J8u4gcLhOzVXOEk,196
37
- nexom/assets/auth_page/login.html,sha256=dMF098lsctmpDWHZL_wSDcqaBSLquiSXzcBZrtc5Phg,3536
38
- nexom/assets/auth_page/signup.html,sha256=1fjw5R02EDFk2pyxqaa7eDU83uKegnXAOVaBLgbfOd0,4014
37
+ nexom/assets/auth/__pycache__/__init__.cpython-313.pyc,sha256=u5wF3QOdS5tOChvwNUS4T8fKJzNlX0__7QsHvXjkr0Q,196
38
+ nexom/assets/auth_page/login.html,sha256=qxw8uxW_WnQn9SMOUlrkwSbe4NFmFG6qK2erjzYrS2U,7096
39
+ nexom/assets/auth_page/signup.html,sha256=Iax5xyrfVRwY1_c_Welc4C44s3cLYslz7uDDSQKk588,9476
39
40
  nexom/assets/error_page/error.html,sha256=JFi47UVxcxef_TTt1hDOuo93_45uSWCfixOJCUQVTs4,1230
40
41
  nexom/assets/gateway/apache_app.conf,sha256=_QeZ0BqpuZaJfBONurNTW1FqJ7-PmunPrfbzAJRP3Qg,370
41
42
  nexom/assets/gateway/nginx_app.conf,sha256=PaHRPGjJEyNiUU9OZiXS9HQhGwSe1oosSZp-6lnlQO0,521
42
43
  nexom/buildTools/__init__.py,sha256=FbaFEMRjOKHNqNR-KuEatZjwPhmJf1CDZmR2hSH7YGk,19
43
- nexom/buildTools/build.py,sha256=DSmHUIHNrXCdLUogmfHvnl9PtO1QOfQyRU15F-HLztk,10782
44
+ nexom/buildTools/build.py,sha256=JJxb5tHBW5WVSx2GWgu4uszP8FUKVSkDMsooFJYg2Vk,10796
44
45
  nexom/buildTools/run.py,sha256=HpSlkrNPFW961qgHjzedjGogdIYRQddhL95g3PcbM5s,5384
45
46
  nexom/core/__init__.py,sha256=_ohRDLTerW9deZyh0WEp-ZB2LExkLvM9f26MhEdcp8g,52
46
- nexom/core/error.py,sha256=1xwAynes65OEjhO8ZFC2lm_u_LGOAm4-nfGK-IedKOo,6199
47
+ nexom/core/error.py,sha256=tGQer5P-d_-F-_maAtOgveZxm26m0xt_SeMv2ZxT5KA,9332
47
48
  nexom/core/log.py,sha256=q0FYz1-kkTUHvNkEBW5V1zvUv1phMYchOqwAfUXGHQI,3016
48
49
  nexom/core/object_html_render.py,sha256=4yT3Aihia4oG62gr1rqZd757wEXsu78mTCCpjpVE7JM,7027
49
50
  nexom/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- nexom/templates/auth.py,sha256=eWThgPR4E7y7YFcQ6rFZaO6yPKGL2zIbBC4SuzQ5M44,2332
51
- nexom-1.0.4.dist-info/licenses/LICENSE,sha256=YbcHyxYLJ5jePeMS_NXpR9yiZjP5skhn32LvcKeknJw,1066
52
- nexom-1.0.4.dist-info/METADATA,sha256=RZkujq6lxxQlzFcGmuMVmk7HeEXVWIsxo04yEYjOrJ4,5886
53
- nexom-1.0.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
54
- nexom-1.0.4.dist-info/entry_points.txt,sha256=0r1egKZmF1MUo25AKPt-2d55sk5Q_EIBOQwD3JC8RgI,46
55
- nexom-1.0.4.dist-info/top_level.txt,sha256=mTyUruscL3rqXvYJRo8KGwDM6PWXRzgf4CamLr8LSX4,6
56
- nexom-1.0.4.dist-info/RECORD,,
51
+ nexom/templates/auth.py,sha256=Fh9nDCJZNIC8JE5_cmpgA6daIBtumVB4x0mRgme100o,4593
52
+ nexom-1.0.5.dist-info/licenses/LICENSE,sha256=YbcHyxYLJ5jePeMS_NXpR9yiZjP5skhn32LvcKeknJw,1066
53
+ nexom-1.0.5.dist-info/METADATA,sha256=D2eIXFEDHIff2s6DYOthznV5MFVCNlgcM-IXdgzEo60,5886
54
+ nexom-1.0.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
55
+ nexom-1.0.5.dist-info/entry_points.txt,sha256=0r1egKZmF1MUo25AKPt-2d55sk5Q_EIBOQwD3JC8RgI,46
56
+ nexom-1.0.5.dist-info/top_level.txt,sha256=mTyUruscL3rqXvYJRo8KGwDM6PWXRzgf4CamLr8LSX4,6
57
+ nexom-1.0.5.dist-info/RECORD,,
File without changes