mirror of
https://framagit.org/framasoft/framaspace/argos.git
synced 2025-04-28 09:52:38 +02:00
✨ — Add "Remember me" checkbox on login (#65)
This commit is contained in:
parent
91a9b27106
commit
0563cf185a
5 changed files with 64 additions and 9 deletions
|
@ -8,6 +8,7 @@
|
|||
- ✨ — The HTTP method used by checks is now configurable
|
||||
- ♻️ — Refactor some agent code
|
||||
- 💄 — Filter form on domains list (#66)
|
||||
- ✨ — Add "Remember me" checkbox on login (#65)
|
||||
|
||||
## 0.5.0
|
||||
|
||||
|
|
|
@ -14,9 +14,19 @@ general:
|
|||
# Can be "production", "dev", "test".
|
||||
# If not present, default value is "production"
|
||||
env: "production"
|
||||
# to get a good string for cookie_secret, run:
|
||||
# To get a good string for cookie_secret, run:
|
||||
# openssl rand -hex 32
|
||||
cookie_secret: "foo_bar_baz"
|
||||
|
||||
# Session duration
|
||||
# Use m for minutes, h for hours, d for days
|
||||
# w for weeks, mo for months, y for years
|
||||
# If not present, default value is "7d"
|
||||
session_duration: "7d"
|
||||
# Session opened with "Remember me" checked
|
||||
# If not present, the "Remember me" feature is not available
|
||||
# remember_me_duration: "1mo"
|
||||
|
||||
# Default delay for checks.
|
||||
# Can be superseeded in domain configuration.
|
||||
# For ex., to run checks every minute:
|
||||
|
|
|
@ -175,16 +175,31 @@ class DbSettings(BaseModel):
|
|||
class General(BaseModel):
|
||||
"""Frequency for the checks and alerts"""
|
||||
|
||||
cookie_secret: str
|
||||
frequency: int
|
||||
db: DbSettings
|
||||
env: Environment = "production"
|
||||
cookie_secret: str
|
||||
session_duration: int = 10080 # 7 days
|
||||
remember_me_duration: Optional[int] = None
|
||||
frequency: int
|
||||
root_path: str = ""
|
||||
alerts: Alert
|
||||
mail: Optional[Mail] = None
|
||||
gotify: Optional[List[GotifyUrl]] = None
|
||||
apprise: Optional[Dict[str, List[str]]] = None
|
||||
|
||||
@field_validator("session_duration", mode="before")
|
||||
def parse_session_duration(cls, value):
|
||||
"""Convert the configured session duration to minutes"""
|
||||
return string_to_duration(value, "minutes")
|
||||
|
||||
@field_validator("remember_me_duration", mode="before")
|
||||
def parse_remember_me_duration(cls, value):
|
||||
"""Convert the configured session duration with remember me feature to minutes"""
|
||||
if value:
|
||||
return string_to_duration(value, "minutes")
|
||||
|
||||
return None
|
||||
|
||||
@field_validator("frequency", mode="before")
|
||||
def parse_frequency(cls, value):
|
||||
"""Convert the configured frequency to minutes"""
|
||||
|
|
|
@ -28,7 +28,11 @@ SEVERITY_LEVELS = {"ok": 1, "warning": 2, "critical": 3, "unknown": 4}
|
|||
|
||||
|
||||
@route.get("/login")
|
||||
async def login_view(request: Request, msg: str | None = None):
|
||||
async def login_view(
|
||||
request: Request,
|
||||
msg: str | None = None,
|
||||
config: Config = Depends(get_config),
|
||||
):
|
||||
token = request.cookies.get("access-token")
|
||||
if token is not None and token != "":
|
||||
manager = request.app.state.manager
|
||||
|
@ -44,7 +48,14 @@ async def login_view(request: Request, msg: str | None = None):
|
|||
else:
|
||||
msg = None
|
||||
|
||||
return templates.TemplateResponse("login.html", {"request": request, "msg": msg})
|
||||
return templates.TemplateResponse(
|
||||
"login.html",
|
||||
{
|
||||
"request": request,
|
||||
"msg": msg,
|
||||
"remember": config.general.remember_me_duration,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@route.post("/login")
|
||||
|
@ -52,6 +63,8 @@ async def post_login(
|
|||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
data: OAuth2PasswordRequestForm = Depends(),
|
||||
rememberme: Annotated[str | None, Form()] = None,
|
||||
config: Config = Depends(get_config),
|
||||
):
|
||||
username = data.username
|
||||
user = await queries.get_user(db, username)
|
||||
|
@ -70,14 +83,22 @@ async def post_login(
|
|||
db.commit()
|
||||
|
||||
manager = request.app.state.manager
|
||||
token = manager.create_access_token(
|
||||
data={"sub": username}, expires=timedelta(days=7)
|
||||
)
|
||||
session_duration = config.general.session_duration
|
||||
if config.general.remember_me_duration is not None and rememberme == "on":
|
||||
session_duration = config.general.remember_me_duration
|
||||
delta = timedelta(minutes=session_duration)
|
||||
token = manager.create_access_token(data={"sub": username}, expires=delta)
|
||||
response = RedirectResponse(
|
||||
request.url_for("get_severity_counts_view"),
|
||||
status_code=status.HTTP_303_SEE_OTHER,
|
||||
)
|
||||
manager.set_cookie(response, token)
|
||||
response.set_cookie(
|
||||
key=manager.cookie_name,
|
||||
value=token,
|
||||
httponly=True,
|
||||
samesite="strict",
|
||||
expires=int(delta.total_seconds()),
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
name="password"
|
||||
type="password"
|
||||
form="login">
|
||||
{% if remember is not none %}
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
name="rememberme"
|
||||
form="login">
|
||||
Remember me
|
||||
</label>
|
||||
{% endif %}
|
||||
<form id="login"
|
||||
method="post"
|
||||
action="{{ url_for('post_login') }}">
|
||||
|
|
Loading…
Reference in a new issue