credibil_dwn/handlers/
protocols_query.rs1use crate::authorization::Authorization;
7use crate::endpoint::{Message, Reply, Status};
8use crate::handlers::verify_grant;
9use crate::interfaces::Descriptor;
10use crate::interfaces::protocols::{Access, Configure, Query, QueryReply};
11use crate::provider::{MessageStore, Provider};
12use crate::store::ProtocolsQueryBuilder;
13use crate::{Result, utils};
14
15pub async fn handle(
22 owner: &str, query: Query, provider: &impl Provider,
23) -> Result<Reply<QueryReply>> {
24 if let Some(filter) = &query.descriptor.filter {
26 utils::uri::validate(&filter.protocol)?;
27 }
28
29 let mut builder = ProtocolsQueryBuilder::new();
31 if let Some(filter) = &query.descriptor.filter {
32 builder = builder.protocol(&filter.protocol);
33 }
34
35 if query.authorize(owner, provider).await? == Access::Published {
37 builder = builder.published(true);
38 }
39
40 let (records, cursor) = MessageStore::query(provider, owner, &builder.build()).await?;
41
42 let mut entries = vec![];
44 for record in records {
45 entries.push(Configure::try_from(record)?);
46 }
47
48 Ok(Reply {
49 status: Status {
50 code: 200,
51 detail: Some("OK".to_string()),
52 },
53 body: Some(QueryReply {
54 entries: Some(entries),
55 cursor,
56 }),
57 })
58}
59
60impl Message for Query {
61 type Reply = QueryReply;
62
63 fn descriptor(&self) -> &Descriptor {
64 &self.descriptor.base
65 }
66
67 fn authorization(&self) -> Option<&Authorization> {
68 self.authorization.as_ref()
69 }
70
71 async fn handle(self, owner: &str, provider: &impl Provider) -> Result<Reply<Self::Reply>> {
72 handle(owner, self, provider).await
73 }
74}
75
76impl Query {
77 async fn authorize(&self, owner: &str, store: &impl MessageStore) -> Result<Access> {
79 let Some(authzn) = &self.authorization else {
80 return Ok(Access::Published);
81 };
82
83 if authzn.author()? == owner {
84 return Ok(Access::Unpublished);
85 }
86
87 let Some(grant_id) = &authzn.payload()?.permission_grant_id else {
89 return Ok(Access::Published);
90 };
91
92 let grant = verify_grant::fetch_grant(owner, grant_id, store).await?;
94 grant.verify(owner, &authzn.signer()?, &self.descriptor.base, store).await?;
95
96 let Some(protocol) = grant.data.scope.protocol() else {
98 return Ok(Access::Unpublished);
99 };
100 let Some(filter) = &self.descriptor.filter else {
102 return Ok(Access::Published);
103 };
104 if protocol != filter.protocol {
106 return Ok(Access::Published);
107 }
108
109 Ok(Access::Unpublished)
110 }
111}