This commit is contained in:
roydfalk 2024-08-18 13:54:58 +02:00
parent 087c126453
commit 2135dfff1f
4 changed files with 409 additions and 30 deletions

View file

@ -176,9 +176,35 @@ namespace _espe.conf
email_address : (null | string); email_address : (null | string);
} }
>; >;
output : { outputs : Array<
authelia : (null | string); {
kind : "authelia_file";
data : {
path : string;
}
}
|
{
kind : "http";
data : {
scheme : ("http" | "https");
host : string;
path : string;
method : ("get" | "post" | "put" | "patch" | "delete" | "head" | "options");
query : (null | string);
headers : Record<string,string>;
}; };
}
|
{
kind : "authelia_call";
data : {
http_scheme : ("http" | "https");
http_host : string;
hash_salt : string;
}
}
>;
}; };
@ -355,10 +381,20 @@ namespace _espe.conf
})) (conf_raw["settings"] ?? {}) })) (conf_raw["settings"] ?? {})
), ),
"admins": (conf_raw["admins"] ?? []), "admins": (conf_raw["admins"] ?? []),
"output": ( "outputs": (
((node_session_output) => ({ ((node_output) => (
"authelia": (node_session_output["authelia"] ?? null), ("authelia" in node_output)
})) (conf_raw["output"] ?? {}) ? [
{
"kind": "authelia_file",
"data": {
"path": node_output["authelia"],
}
}
]
: [
]
)) (conf_raw["output"] ?? {})
), ),
}; };
break; break;
@ -540,14 +576,205 @@ namespace _espe.conf
})) (conf_raw["settings"] ?? {}) })) (conf_raw["settings"] ?? {})
), ),
"admins": (conf_raw["admins"] ?? []), "admins": (conf_raw["admins"] ?? []),
"output": ( "outputs": (
((node_session_output) => ({ ((node_output) => (
"authelia": (node_session_output["authelia"] ?? null), ("authelia" in node_output)
})) (conf_raw["output"] ?? {}) ? [
{
"kind": "authelia_file",
"data": {
"path": node_output["authelia"],
}
}
]
: [
]
)) (conf_raw["output"] ?? {})
), ),
}; };
break; break;
} }
case 3: {
_data = {
"general": (
((node_general) => ({
"language": (node_general["language"] ?? null),
"verification_secret": (node_general["verification_secret"] ?? null),
})) (conf_raw["general"] ?? {})
),
"log": (
((node_log) => node_log.map(
(node_log_entry : any) => ({
"kind": node_log_entry["kind"],
"data": Object.assign(
{
"format": "human_readable",
"threshold": "notice",
},
(node_log_entry["data"] ?? {})
)
})
)) (
conf_raw["log"]
??
[
{
"kind": "console",
"data": {
}
},
]
)
),
"server": (
((node_server) => ({
"port": (node_server["port"] ?? 4916),
"path_base": (node_server["path_base"] ?? ""),
})) (conf_raw["server"] ?? {})
),
"database": (
((node_database) => {
const kind : string = (node_database["kind"] ?? "sqlite");
const node_database_data_raw = (node_database["data"] ?? {});
switch (kind) {
case "sqlite": {
return {
"kind": kind,
"data": {
"path": (node_database_data_raw["path"] ?? "data.sqlite"),
}
};
break;
}
case "postgresql": {
return {
"kind": kind,
"data": node_database_data_raw,
};
break;
}
default: {
throw (new Error("unhandled"));
break;
}
}
}) (conf_raw["database"] ?? {})
),
"email_sending": (
((node_email_sending) => {
const kind : string = (node_email_sending["kind"] ?? "console");
const data_raw = (node_email_sending["data"] ?? {});
switch (kind) {
case "regular": {
return {
"kind": kind,
"data": {
"smtp_credentials": (data_raw["smtp_credentials"] ?? null),
"sender": data_raw["sender"],
}
};
break;
}
case "redirect": {
return {
"kind": kind,
"data": {
"smtp_credentials": (data_raw["smtp_credentials"] ?? null),
"sender": data_raw["sender"],
"target": data_raw["target"],
}
};
break;
}
case "console": {
return {
"kind": kind,
"data": {
}
};
break;
}
case "drop": {
return {
"kind": kind,
"data": {
}
};
break;
}
default: {
throw (new Error("unhandled"));
break;
}
}
}) (conf_raw["email_sending"] ?? {})
),
"session_management": (
((node_session_management) => ({
"in_memory": (node_session_management["in_memory"] ?? true),
"drop_all_at_start": (node_session_management["drop_all_at_start"] ?? true),
"lifetime": (node_session_management["lifetime"] ?? 900),
})) (conf_raw["session_management"] ?? {})
),
"settings": (
((node_settings) => ({
"organisation": {
"name": ((node_settings["organisation"] ?? {})["name"] ?? "Example Orginsation"), // TODO: mandatory?
"domain": ((node_settings["organisation"] ?? {})["domain"] ?? "example.org"), // TODO: mandatory?
},
"misc": (
((node_settings_misc) => ({
"prefix_for_veiled_email_addresses": (node_settings_misc["prefix_for_veiled_email_addresses"] ?? "member-"),
"facultative_membership_number": (node_settings_misc["facultative_membership_number"] ?? false),
"auto_register": (node_settings_misc["auto_register"] ?? false),
})) (node_settings["misc"] ?? {})
),
"summon_email": (
((node_settings_summon_email) => ({
"remark": (node_settings_summon_email["remark"] ?? null),
})) (node_settings["summon_email"] ?? {})
),
"password_policy": (
((node_settings_password_policy) => ({
"minimum_length": (
("minimum_length" in node_settings_password_policy)
? node_settings_password_policy["minimum_length"]
: 8
),
"maximum_length": (
("maximum_length" in node_settings_password_policy)
? node_settings_password_policy["maximum_length"]
: 240
),
"must_contain_letter": (node_settings_password_policy["must_contain_letter"] ?? true),
"must_contain_number": (node_settings_password_policy["must_contain_number"] ?? true),
"must_contain_special_character": (node_settings_password_policy["must_contain_special_character"] ?? true),
})) (node_settings["password_policy"] ?? {})
),
"password_change": (
((node_settings_password_change) => ({
"cooldown_time": (node_settings_password_change["cooldown_time"] ?? 86400),
})) (node_settings["password_change"] ?? {})
),
"name_index": (
((node_settings_password_policy) => ({
"veil": (node_settings_password_policy["veil"] ?? true),
"salt": (node_settings_password_policy["salt"] ?? ""),
})) (node_settings["name_index"] ?? {})
),
"connections": (
((node_settings_connections) => ({
"frontend_url_base": (node_settings_connections["frontend_url_base"] ?? null),
"login_url": (node_settings_connections["login_url"] ?? null),
})) (node_settings["connections"] ?? {})
),
})) (conf_raw["settings"] ?? {})
),
"admins": (conf_raw["admins"] ?? []),
"outputs": (conf_raw["outputs"] ?? []),
};
break;
}
default: { default: {
throw (new Error("invalid conf version: " + conf_raw["version"])); throw (new Error("invalid conf version: " + conf_raw["version"]));
break; break;

View file

@ -317,20 +317,33 @@ async function main(
); );
// outputs // outputs
{ {
if (_espe.conf.get().output.authelia === null) { _espe.conf.get().outputs.forEach(
// do nothing output_description => {
} switch (output_description.kind) {
else { default: {
_espe.service.member.listen_change( lib_plankton.log.warning(
async () => { "output_kind_unhandled",
const authelia_export : string = await _espe.service.member.export_authelia_user_file(); {
lib_plankton.file.write( "description": output_description,
_espe.conf.get().output.authelia,
authelia_export
);
} }
); );
break;
} }
case "authelia_file": {
_espe.service.member.output_authelia_file(output_description.data);
break;
}
case "http": {
_espe.service.member.output_http(output_description.data);
break;
}
case "authelia_call": {
_espe.service.member.output_authelia_call(output_description.data);
break;
}
}
}
);
} }
const rest_subject : lib_plankton.rest.type_rest = _espe.api.make(); const rest_subject : lib_plankton.rest.type_rest = _espe.api.make();

View file

@ -253,7 +253,7 @@ namespace _espe.service.member
/** /**
* gibt die vollständigen Daten aller Mitglieder aus * gibt die vollständigen Daten aller Mitglieder aus
*/ */
async function dump( export async function dump(
) : Promise< ) : Promise<
Array< Array<
{ {
@ -776,11 +776,11 @@ namespace _espe.service.member
/** /**
* @todo check validity (e.g. username characters) * @todo check validity (e.g. username characters)
*/ */
export async function export_authelia_user_file( export async function export_authelia_user_data(
options : { options : {
custom_data ?: (null | Array<_espe.type.member_object>); custom_data ?: (null | Array<_espe.type.member_object>);
} = {} } = {}
) : Promise<string> ) : Promise<any>
{ {
options = Object.assign( options = Object.assign(
{ {
@ -789,8 +789,6 @@ namespace _espe.service.member
options options
); );
const nm_yaml = require("yaml");
type type_entry = { type type_entry = {
disabled : boolean; disabled : boolean;
displayname : string; displayname : string;
@ -842,10 +840,150 @@ namespace _espe.service.member
), ),
Object.fromEntries, Object.fromEntries,
(x : Record<string, type_entry>) => ({"users": x}), (x : Record<string, type_entry>) => ({"users": x}),
(x : {users : Record<string, type_entry>}) => nm_yaml.stringify(x),
] ]
); );
} }
/**
*/
export async function export_authelia_user_file(
options : {
custom_data ?: (null | Array<_espe.type.member_object>);
} = {}
) : Promise<string>
{
options = Object.assign(
{
"custom_data": null,
},
options
);
const nm_yaml = require("yaml");
return nm_yaml.stringify(await export_authelia_user_data(options));
}
/**
*/
export async function output_authelia_file(
output_parameters : {
path : string;
}
) : Promise<void>
{
await lib_plankton.file.write(
output_parameters.path,
await _espe.service.member.export_authelia_user_file()
);
}
/**
*/
export async function output_http(
output_parameters : {
scheme : ("http" | "https");
host : string;
path : string;
method : ("get" | "post" | "put" | "patch" | "delete" | "head" | "options");
query : (null | string);
headers : Record<string,string>;
}
) : Promise<void>
{
const http_request : lib_plankton.http.type_request = {
"scheme": output_parameters.scheme,
"host": output_parameters.host,
"path": output_parameters.path,
"version": "HTTP/1.1",
"method": (
(
{
"get": lib_plankton.http.enum_method.get,
"post": lib_plankton.http.enum_method.post,
"put": lib_plankton.http.enum_method.put,
"patch": lib_plankton.http.enum_method.patch,
"delete": lib_plankton.http.enum_method.delete,
"head": lib_plankton.http.enum_method.head,
"options": lib_plankton.http.enum_method.options,
}[output_parameters.method]
)
??
lib_plankton.http.enum_method.post
),
"query": output_parameters.query,
"headers": output_parameters.headers,
"body": lib_plankton.json.encode(await _espe.service.member.dump()),
};
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
http_request
);
if (! ((http_response.status_code >= 200) && (http_response.status_code < 400))) {
lib_plankton.log.warning(
"output_http_failed",
{
"http_request": http_request,
"http_response_status_code": http_response.status_code,
}
);
}
else {
// do nothing
}
}
/**
*/
export async function output_authelia_call(
output_parameters : {
http_scheme : ("http" | "https");
http_host : string;
hash_salt : string;
}
) : Promise<void>
{
const timestamp : float = lib_plankton.base.get_current_timestamp();
const auth : string = lib_plankton.sha256.get(
timestamp.toFixed(0)
+
output_parameters.hash_salt
);
const http_request : lib_plankton.http.type_request = {
"scheme": output_parameters.http_scheme,
"host": output_parameters.http_host,
"path": "/users/set",
"version": "HTTP/1.1",
"method": lib_plankton.http.enum_method.put,
"query": lib_plankton.string.coin(
"?timestamp={{timestamp}}&auth={{auth}}",
{
"timestamp": timestamp.toFixed(0),
"auth": auth,
}
),
"headers": {
"Content-Type": "application/json",
},
"body": lib_plankton.json.encode(await _espe.service.member.export_authelia_user_data()),
};
const http_response : lib_plankton.http.type_response = await lib_plankton.http.call(
http_request
);
if (http_response.status_code !== 200) {
lib_plankton.log.warning(
"output_authelia_callback_failed",
{
"http_response_status_code": http_response.status_code,
}
);
}
else {
// do nothing
}
}
} }

View file

@ -52,3 +52,4 @@ def main():
main() main()