From 1f8106796e21d9bd659774705a33feda069053d1 Mon Sep 17 00:00:00 2001 From: Tommaso Bailetti Date: Wed, 21 Feb 2024 11:18:33 +0100 Subject: [PATCH 1/3] feat(api-moduled): added get-password-policy api --- .../handlers/get-password-policy/post | 75 +++++++++++++++++++ .../get-password-policy/validate-output.json | 21 ++++++ 2 files changed, 96 insertions(+) create mode 100755 imageroot/api-moduled/handlers/get-password-policy/post create mode 100644 imageroot/api-moduled/handlers/get-password-policy/validate-output.json diff --git a/imageroot/api-moduled/handlers/get-password-policy/post b/imageroot/api-moduled/handlers/get-password-policy/post new file mode 100755 index 0000000..ef7bbfa --- /dev/null +++ b/imageroot/api-moduled/handlers/get-password-policy/post @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +# +# Copyright (C) 2024 Nethesis S.r.l. +# SPDX-License-Identifier: GPL-3.0-or-later +# + +import json +import sys +import subprocess +import os + +SECONDS_PER_DAY = 86400 +ldap_suffix = os.environ["LDAP_SUFFIX"] + +ldapsearch_proc = subprocess.run(["podman", "exec", "openldap", + "ldapsearch", "-LLL", "-b", f"cn=default,ou=PPolicy,{ldap_suffix}", "-s", "base" + ], text=True, capture_output=True, check=True) + + +ppolicy = { + "expiration": { + "min_age": 0, + "max_age": 0, + "enforced": False, + }, + "strength": { + "enforced": False, + "history_length": 0, + "password_min_length": 0, + "complexity_check": False, + } +} + +for line in ldapsearch_proc.stdout.split("\n"): + if not line: + continue + + lattr, lval = line.split(":", 1) + lval = lval.strip() # trim wrapping blanks + + if lattr == "pwdMinAge": + ppolicy["expiration"]["min_age"] = int(lval) // SECONDS_PER_DAY + elif lattr == "pwdMaxAge": + ppolicy["expiration"]["max_age"] = int(lval) // SECONDS_PER_DAY + elif lattr == "pwdMinLength": + ppolicy["strength"]["password_min_length"] = int(lval) + elif lattr == "pwdInHistory": + ppolicy["strength"]["history_length"] = int(lval) + elif lattr == "pwdUseCheckModule": + ppolicy["strength"]["complexity_check"] = lval == 'TRUE' + +if ppolicy["strength"]["complexity_check"] is True or \ + ppolicy["strength"]["history_length"] > 0 or \ + ppolicy["strength"]["password_min_length"] > 0: + ppolicy["strength"]["enforced"] = True +else: + ppolicy["strength"]["enforced"] = False + ppolicy["strength"]["history_length"] = 12 + ppolicy["strength"]["password_min_length"] = 8 + ppolicy["strength"]["complexity_check"] = True + +if ppolicy["expiration"]["min_age"] > 0 or \ + ppolicy["expiration"]["max_age"] > 0: + ppolicy["expiration"]["enforced"] = True +else: + ppolicy["expiration"]["enforced"] = False + ppolicy["expiration"]["min_age"] = 0 + ppolicy["expiration"]["max_age"] = 180 + +json.dump({ + "status": "success", + "message": "password_policy", + "policy": ppolicy +}, fp=sys.stdout) diff --git a/imageroot/api-moduled/handlers/get-password-policy/validate-output.json b/imageroot/api-moduled/handlers/get-password-policy/validate-output.json new file mode 100644 index 0000000..599a117 --- /dev/null +++ b/imageroot/api-moduled/handlers/get-password-policy/validate-output.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "get password policy", + "$id": "http://schema.nethserver.org/ns8-openldap/api-moduled/handlers/get-password-policy/validate-output.json", + "type": "object", + "required": [ + "status", + "message" + ], + "properties": { + "status": { + "enum": [ + "success", + "failure" + ] + }, + "message": { + "type": "string" + } + } +} From 80b78f00f10fc9f11bb84d8286741eb7f9974b64 Mon Sep 17 00:00:00 2001 From: Tommaso Bailetti Date: Wed, 21 Feb 2024 16:40:18 +0100 Subject: [PATCH 2/3] chore(deps): update dependency nethserver/ns8-user-manager to v0.8.1 --- build-images.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-images.sh b/build-images.sh index 7f03c0a..8f3225f 100644 --- a/build-images.sh +++ b/build-images.sh @@ -33,7 +33,7 @@ fi buildah add "${container}" imageroot /imageroot # Copy ui of ns8-user-manager -user_manager_version=v0.7.0 +user_manager_version=v0.8.1 curl -f -L -O https://github.com/NethServer/ns8-user-manager/releases/download/${user_manager_version}/ns8-user-manager-${user_manager_version}.tar.gz buildah add "${container}" ns8-user-manager-${user_manager_version}.tar.gz /imageroot/api-moduled/public/ From cd376285c8e23e043f35778a02adeb061c632fbb Mon Sep 17 00:00:00 2001 From: Tommaso Bailetti Date: Fri, 23 Feb 2024 09:21:15 +0100 Subject: [PATCH 3/3] fix: added password policy scope to auth --- imageroot/api-moduled/handlers/login/post | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imageroot/api-moduled/handlers/login/post b/imageroot/api-moduled/handlers/login/post index 519f1bf..bb9f154 100755 --- a/imageroot/api-moduled/handlers/login/post +++ b/imageroot/api-moduled/handlers/login/post @@ -38,10 +38,10 @@ oclaims = { if proc_whoami.returncode == 49 and "Password expired" in proc_whoami.stderr: # Password must be changed immediately: return a token limited to # password changing: - oclaims["scope"] = ["change-password"] + oclaims["scope"] = ["change-password", "get-password-policy"] elif proc_whoami.returncode != 0: sys.exit(3) # Login failed elif "domain admins" not in oclaims["groups"]: - oclaims["scope"] = ["change-password"] + oclaims["scope"] = ["change-password", "get-password-policy"] json.dump(oclaims, fp=sys.stdout)