[task-192] [int]

This commit is contained in:
Fenris Wolf 2024-12-01 15:21:20 +01:00
parent 6f1437b55a
commit 2cb46cd485
3 changed files with 227 additions and 84 deletions

View file

@ -9,12 +9,12 @@ namespace _zeitbild.api
) : void ) : void
{ {
register< register<
lib_plankton.xml.type_node_data,
( (
null null
| |
lib_plankton.xml.type_node_data lib_plankton.xml.type_node_data
), )
lib_plankton.xml.type_node_data
>( >(
rest_subject, rest_subject,
lib_plankton.caldav.enum_method.propfind, lib_plankton.caldav.enum_method.propfind,
@ -48,6 +48,9 @@ namespace _zeitbild.api
), ),
// "restriction": restriction_basic_auth, // "restriction": restriction_basic_auth,
"restriction": restriction_none, "restriction": restriction_none,
/**
* @todo heed stuff.input
*/
"execution": async (stuff) => { "execution": async (stuff) => {
const user_id : (null | type_user_id) = await _zeitbild.api.web_auth( const user_id : (null | type_user_id) = await _zeitbild.api.web_auth(
stuff.headers["Authorization"] stuff.headers["Authorization"]
@ -71,17 +74,30 @@ namespace _zeitbild.api
); );
} }
else { else {
return ( if (stuff.input === null) {
_zeitbild.service.caldav.projects(user_id) return Promise.resolve(
.then( {
(output) => Promise.resolve( "status_code": 400,
{ "data": null,
"status_code": 207, }
"data": output, );
} }
else {
return (
_zeitbild.service.caldav.projects(
stuff.input,
user_id
) )
) .then(
); (output) => Promise.resolve(
{
"status_code": 207,
"data": output,
}
)
)
);
}
} }
} }
} }

View file

@ -287,6 +287,9 @@ namespace _zeitbild.conf
"nullable": false, "nullable": false,
"type": "object", "type": "object",
"properties": { "properties": {
/**
* @todo make mandatory
*/
"auth_salt": { "auth_salt": {
"nullable": false, "nullable": false,
"type": "string", "type": "string",

View file

@ -78,7 +78,7 @@ namespace _zeitbild.service.caldav
string, string,
lib_plankton.webdav.type_data_prop_value lib_plankton.webdav.type_data_prop_value
> = { > = {
// webdav 1 // RFC2518
/** /**
* @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.2 * @see https://datatracker.ietf.org/doc/html/rfc2518#section-13.2
@ -125,7 +125,7 @@ namespace _zeitbild.service.caldav
} }
}, },
// webdav 2 // RFCP3744
/** /**
* @see https://datatracker.ietf.org/doc/html/rfc3744#section-4.2 * @see https://datatracker.ietf.org/doc/html/rfc3744#section-4.2
@ -151,8 +151,15 @@ namespace _zeitbild.service.caldav
] ]
}, },
// caldav // RFC4791
/**
* @see https://datatracker.ietf.org/doc/html/rfc4791#section-5.2.3
*/
"supported-calendar-component-set": {
"kind": "primitive",
"data": "VEVENT"
},
/** /**
* @see https://datatracker.ietf.org/doc/html/rfc4791#section-6.2.1 * @see https://datatracker.ietf.org/doc/html/rfc4791#section-6.2.1
*/ */
@ -161,7 +168,17 @@ namespace _zeitbild.service.caldav
"data": "/caldav/project" "data": "/caldav/project"
}, },
// WebDAV Current Principal Extension // RFC4918
/**
* @see https://datatracker.ietf.org/doc/html/rfc4918#section-15.6
*/
"getetag": {
"kind": "primitive",
"data": ""
},
// RFC5397
/** /**
* @see https://datatracker.ietf.org/doc/html/rfc5397#section-3 * @see https://datatracker.ietf.org/doc/html/rfc5397#section-3
@ -171,6 +188,16 @@ namespace _zeitbild.service.caldav
"data": "/caldav" "data": "/caldav"
}, },
// RFC6638
/**
* @see https://datatracker.ietf.org/doc/html/rfc6638#section-2.4.1
*/
"calendar-user-address-set": {
"kind": "primitive",
"data": ""
},
// unknown // unknown
/* /*
@ -189,10 +216,6 @@ namespace _zeitbild.service.caldav
"checked-out": { "checked-out": {
"kind": "none", "kind": "none",
"data": null "data": null
},
"calendar-user-address-set": {
"kind": "none",
"data": null
}, },
*/ */
}; };
@ -307,80 +330,181 @@ namespace _zeitbild.service.caldav
/** /**
* @todo heed input properly
*/ */
export function projects( export function projects(
input : lib_plankton.xml.type_node_data,
user_id : type_user_id user_id : type_user_id
) : Promise<lib_plankton.xml.type_node_data> ) : Promise<lib_plankton.xml.type_node_data>
{ {
return ( const answers : Record<
_zeitbild.service.calendar.overview(user_id) string,
.then( ((stuff : any) => lib_plankton.webdav.type_data_prop_value)
(data_raw) => Promise.resolve( > = {
data_raw "displayname": (stuff) => ({
.map( "kind": "primitive",
(entry) => ({ "data": stuff["name"]
"id": entry.id, }),
"name": entry.name, "resourcetype": () => ({
"access_level": _zeitbild.value_object.access_level.to_string(entry.access_level), "kind": "resourcetype",
}) "data": {
"kind": "collection",
"type": "calendar",
}
}),
};
/**
* @todo remove
*/
lib_plankton.log.info(
"service.caldav.input",
input
);
/**
* @todo check data structure
*/
if (
! (
(input.kind === "complex")
&&
(input.data.tag === "propfind")
&&
(input.data.children.length === 1)
&&
(input.data.children[0].kind === "complex")
&&
(input.data.children[0].data.tag === "prop")
&&
input.data.children[0].data.children.every(
node => (node.kind === "complex")
)
)
) {
throw (new Error("wrong input structure"));
}
else {
const props : Array<string> = (
input
.data.children
[0]
.data.children
.map(
(node) => node.data.tag
)
);
/**
* @todo remove
*/
lib_plankton.log.info(
"service.caldav.props",
props
);
return (
_zeitbild.service.calendar.overview(user_id)
.then(
(data_raw) => Promise.resolve(
data_raw
.map(
(entry) => ({
"id": entry.id,
"name": entry.name,
"access_level": _zeitbild.value_object.access_level.to_string(entry.access_level),
})
)
) )
) )
) .then(
.then( (data) => Promise.resolve(
(data) => Promise.resolve( {
{ "kind": "root",
"kind": "root", "data": {
"data": { "version": "1.0",
"version": "1.0", "encoding": "utf-8",
"encoding": "utf-8", "content": lib_plankton.webdav.data_multistatus_encode_xml(
"content": lib_plankton.webdav.data_multistatus_encode_xml( {
{ "responses": data.map(
"responses": data.map( (entry) => ({
(entry) => ({ "href": lib_plankton.string.coin(
"href": lib_plankton.string.coin( "/caldav/project/{{id}}",
"/caldav/project/{{id}}",
{
"id": entry.id.toFixed(0),
}
),
"body": {
"propstats": [
{ {
"prop": [ "id": entry.id.toFixed(0),
{
"name": "D:displayname",
"value": {
"kind": "primitive",
"data": entry.name,
},
},
{
"name": "D:resourcetype",
"value": {
"kind": "resourcetype",
"data": {
"kind": "collection",
"type": "calendar",
}
}
},
],
"status": "HTTP/1.1 200 OK",
"description": null,
} }
], ),
}, "body": {
"description": null, /*
}) "propstats": [
), {
"description": null, "prop": [
} {
) "name": "D:displayname",
"value": {
"kind": "primitive",
"data": entry.name,
},
},
{
"name": "D:resourcetype",
"value": {
"kind": "resourcetype",
"data": {
"kind": "collection",
"type": "calendar",
}
}
},
],
"status": "HTTP/1.1 200 OK",
"description": null,
}
],
*/
"propstats": props.map(
prop => {
const prop_parts : Array<string> = prop.toLowerCase().split(":");
const prop_normalized : string = ((prop_parts.length <= 1) ? prop_parts[0] : prop_parts.slice(1).join(":"));
return (
(! (prop_normalized in answers))
?
{
"prop": [
{
"name": prop,
"value": {
"kind": "none",
"data": null
}
},
],
"status": "HTTP/1.1 200 OK",
"description": null,
}
:
{
"prop": [
{
"name": prop,
"value": answers[prop_normalized](entry),
},
],
"status": "HTTP/1.1 404 Not Found",
"description": null,
}
);
}
)
},
"description": null,
})
),
"description": null,
}
)
}
} }
} )
) )
) );
); }
} }
} }