[mod] auth:oidc zum laufen gebracht, muss aber noch besser angebunden und abstrahier werden

This commit is contained in:
Fenris Wolf 2024-09-26 18:59:46 +02:00
parent 8611bb9445
commit 0c295e93cd
3 changed files with 156 additions and 58 deletions

View file

@ -50,40 +50,68 @@ namespace _zeitbild.api
"response_body_encode": (output => Buffer.from(output)), "response_body_encode": (output => Buffer.from(output)),
"restriction": restriction_none, "restriction": restriction_none,
"execution": async (stuff) => { "execution": async (stuff) => {
_zeitbild.auth.control( const data : {
{ token : string;
"kind": "authorization_callback", userinfo : {
"data": { name : (null | string);
"stuff": stuff.query_parameters, email : (null | string);
"cookie": (stuff.headers["Cookie"] ?? stuff.headers["cookie"]), };
} } = await lib_plankton.auth.oidc.handle_authorization_callback(
} _zeitbild.auth.oidc_subject(),
(stuff.headers["Cookie"] ?? stuff.headers["cookie"] ?? null),
stuff.query_parameters
); );
return ( if (data.userinfo.name === null) {
_zeitbild.auth.execute( return Promise.reject(
undefined new Error(
) "IDP did not return user name"
.then( )
(name) => lib_plankton.session.begin(name) );
) }
.then( else {
(session_key) => Promise.resolve({ try {
await _zeitbild.service.user.add(
{
"name": data.userinfo.name,
"email_address": data.userinfo.email,
}
);
lib_plankton.log.info(
"user_provisioned",
{
"name": data.userinfo.name,
}
);
}
catch (error) {
// do nothing
}
const session_key : string = await lib_plankton.session.begin(
data.userinfo.name,
{
"data": {
"oidc_token": data.token,
}
}
);
const redirect_uri_template : string = _zeitbild.auth.oidc_get_redirect_uri_template("foo");
return Promise.resolve(
{
"status_code": 200, "status_code": 200,
"data": lib_plankton.string.coin( "data": lib_plankton.string.coin(
"<html><head><meta http-equiv=\"refresh\" content=\"0; url={{url}}\" /></head><body></body></html>", "<html><head><meta http-equiv=\"refresh\" content=\"0; url={{url}}\" /></head><body></body></html>",
{ {
// TODO: get url from frontend
"url": lib_plankton.string.coin( "url": lib_plankton.string.coin(
"http://localhost:8888/#oidc_finish,session_key={{session_key}}", redirect_uri_template,
{ {
"session_key": session_key, "session_key": session_key,
} }
), ),
} }
), ),
}) }
) );
); }
}, },
} }
); );

View file

@ -9,17 +9,14 @@ namespace _zeitbild.api
) : void ) : void
{ {
lib_plankton.rest.register< lib_plankton.rest.register<
{ any,
name : string;
password : string;
},
{ {
kind : string; kind : string;
data : any; data : any;
} }
>( >(
rest_subject, rest_subject,
lib_plankton.http.enum_method.get, lib_plankton.http.enum_method.post,
"/session/prepare", "/session/prepare",
{ {
"description": "gibt die nötigen Werkzeuge für eine Anmeldung aus", "description": "gibt die nötigen Werkzeuge für eine Anmeldung aus",
@ -30,8 +27,8 @@ namespace _zeitbild.api
"nullable": false "nullable": false
}), }),
"restriction": restriction_none, "restriction": restriction_none,
"execution": async () => { "execution": async (stuff) => {
const preparation = await _zeitbild.auth.prepare(); const preparation = await _zeitbild.auth.prepare(stuff.input);
return Promise.resolve({ return Promise.resolve({
"status_code": 200, "status_code": 200,
"data": preparation, "data": preparation,

View file

@ -11,6 +11,60 @@ namespace _zeitbild.auth
) = null; ) = null;
/**
*/
let _oidc_redict_uri_template_map : (
null
|
lib_plankton.map.type_map<string, string>
) = null;
/**
*/
export function oidc_subject(
)
{
return lib_plankton.auth.oidc.make(
{
"url_authorization": _zeitbild.conf.get().authentication.data.url_authorization,
"url_token": _zeitbild.conf.get().authentication.data.url_token,
"url_userinfo": _zeitbild.conf.get().authentication.data.url_userinfo,
"client_id": _zeitbild.conf.get().authentication.data.client_id,
"client_secret": _zeitbild.conf.get().authentication.data.client_secret,
"url_redirect": (_zeitbild.conf.get().authentication.data.backend_url_base + "/session/oidc"),
"scopes": [
"openid",
"profile",
"email",
],
"label": _zeitbild.conf.get().authentication.data.label,
}
);
}
/**
*/
export function oidc_get_redirect_uri_template(
key : string
) : string
{
if (_oidc_redict_uri_template_map === null) {
throw (new Error("apparently not initialized yet"));
}
else {
lib_plankton.log.info(
"oidc_redirect_uri_templates",
{
"val": lib_plankton.map.dump(_oidc_redict_uri_template_map),
}
);
return _oidc_redict_uri_template_map.get(key);
}
}
/** /**
*/ */
export function init( export function init(
@ -34,23 +88,12 @@ namespace _zeitbild.auth
break; break;
} }
case "oidc": { case "oidc": {
_subject = lib_plankton.auth.oidc.implementation_auth( _oidc_redict_uri_template_map = lib_plankton.map.simplemap.implementation_map(
{ lib_plankton.map.simplemap.make(
"url_authorization": _zeitbild.conf.get().authentication.data.url_authorization, )
"url_token": _zeitbild.conf.get().authentication.data.url_token,
"url_userinfo": _zeitbild.conf.get().authentication.data.url_userinfo,
"client_id": _zeitbild.conf.get().authentication.data.client_id,
"client_secret": _zeitbild.conf.get().authentication.data.client_secret,
"url_redirect": (_zeitbild.conf.get().authentication.data.backend_url_base + "/session/oidc"),
"scopes": [
"openid",
"profile",
"email",
],
"label": _zeitbild.conf.get().authentication.data.label,
"login_url_mode": "log",
}
); );
// TODO
return Promise.resolve(undefined);
break; break;
} }
default: { default: {
@ -65,21 +108,49 @@ namespace _zeitbild.auth
/** /**
*/ */
export function prepare( export function prepare(
input : any
) : Promise<{kind : string; data : any;}> ) : Promise<{kind : string; data : any;}>
{ {
if (_subject === null) { switch (_zeitbild.conf.get().authentication.kind) {
return Promise.reject(new Error("not initialized yet")); case "oidc": {
} const subject : lib_plankton.auth.oidc.type_subject = oidc_subject();
else { if (_oidc_redict_uri_template_map === null) {
return ( throw (new Error("apparently not initialized yet"));
_subject.login_prepare() }
.then( else {
(data : any) => ({ _oidc_redict_uri_template_map.set(
"kind": _zeitbild.conf.get().authentication.kind, "foo", // TODO proper key
"data": data, input["oidc_redirect_uri_template"]
}) );
) return Promise.resolve(
); {
"kind": "oidc",
"data": {
"url": lib_plankton.auth.oidc.authorization_url(subject),
"label": subject.parameters.label,
}
}
);
}
break;
}
default: {
if (_subject === null) {
return Promise.reject(new Error("not initialized yet"));
}
else {
return (
_subject.login_prepare()
.then(
(data : any) => ({
"kind": _zeitbild.conf.get().authentication.kind,
"data": data,
})
)
);
}
break;
}
} }
} }
@ -99,6 +170,8 @@ namespace _zeitbild.auth
} }
/**
*/
export function control( export function control(
input : any input : any
) : Promise<void> ) : Promise<void>