Skip to content

Commit 9f0918d

Browse files
feat: public lists
1 parent d3bb95d commit 9f0918d

17 files changed

+788
-125
lines changed

esbuild.mjs

+2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ let ctx = await esbuild.context({
88
"./ui/html/invite.html",
99
"./ui/html/invites.html",
1010
"./ui/html/tasks.html",
11+
"./ui/html/tasks-public.html",
1112
"./ui/html/settings.html",
1213
"./ui/html/about.html",
1314
"./ui/html/edit-list.html",
1415
"./ui/html/edit-task.html",
16+
"./ui/html/show-task.html",
1517
"./ui/css/udjat.css",
1618
"./ui/css/style.css",
1719
"./ui/css/soria.woff2",

maat/app/maat-api.hoon

+10-50
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,19 @@
8686
::
8787
%'GET'
8888
~& > '%maat-api: GET'
89-
?. auth
90-
[(send [401 ~ [%plain "401 - Unauthorized"]]) state]
9189
?+ site [(send [404 ~ [%plain "404 - Not Found"]]) state]
9290
::
9391
[%apps %maat %api @t ~]
9492
=/ endpoint (snag 3 `(list @t)`site)
9593
?+ endpoint [(send [404 ~ [%plain "404 - Not Found"]]) state]
96-
94+
::
9795
%invites
96+
?. auth
97+
[(send [401 ~ [%plain "401 - Unauthorized"]]) state]
9898
=/ path /(scot %p our.bowl)/maat/(scot %da now.bowl)/invs/noun
9999
=/ invs .^(invs %gx path)
100100
[(send [200 ~ [%json (groups:enjs invs)]]) state]
101-
101+
::
102102
%lists
103103
=/ path /(scot %p our.bowl)/maat/(scot %da now.bowl)/groups/noun
104104
=/ groups .^(groups %gx path)
@@ -121,22 +121,13 @@
121121
[(send [404 ~ [%plain "404 - Not Found"]]) state]
122122
::
123123
%version
124-
[(send [200 ~ [%json (version:enjs '2024-06-21.2')]]) state]
124+
[(send [200 ~ [%json (version:enjs '2024-06-30.1')]]) state]
125125
::
126126
%members
127+
?. auth
128+
[(send [401 ~ [%plain "401 - Unauthorized"]]) state]
127129
[(send [200 ~ [%json (ships:enjs reg)]]) state]
128-
::::
129-
::%castoffs
130-
::=/ regmod `(set @tas)`(silt (skim ~(tap in reg) |=(m=member ?~(`(unit @p)`(slaw %p `@t`m) %.n %.y))))
131-
::=/ aclmod `(set @tas)`(~(run in acl) |=(=@p `@tas`(scot %p `@t`p)))
132-
::=/ castoffs (~(dif in regmod) aclmod)
133-
::[(send [200 ~ [%json (members:enjs castoffs)]]) state]
134-
::::
135-
:: %invitees
136-
:: =/ path /(scot %p our.bowl)/maat/(scot %da now.bowl)/invs/noun
137-
:: =, .^(=invs %gx path)
138-
:: [(send [200 ~ [%json (ships:enjs (val by invs))]]) state]
139-
::::
130+
::
140131
%tasks
141132
=/ filter-by-done
142133
?~ (find [[key='done' value='true'] ~] args)
@@ -163,15 +154,6 @@
163154
=/ raw (apply tasks |=(=task ~(tap in tags.task)))
164155
=/ =tags (silt `(list @tas)`(flatten raw))
165156
[(send [200 ~ [%json (tags:enjs tags)]]) state]
166-
::::
167-
:: %balances
168-
::=/ path /(scot %p our.bowl)/tahuti/(scot %da now.bowl)/[gid]/net/noun
169-
::=/ net .^(net %gx path)
170-
::[(send [200 ~ [%json (net:enjs [net currency.group])]]) state]
171-
:: %reimbursements
172-
::=/ path /(scot %p our.bowl)/tahuti/(scot %da now.bowl)/[gid]/rei/noun
173-
::=/ rei .^(rei %gx path)
174-
::[(send [200 ~ [%json (rei:enjs [rei currency.group])]]) state]
175157
==
176158
[%apps %maat %api %lists @t %tasks @t ~]
177159
=/ gid (snag 4 `(list @t)`site)
@@ -241,11 +223,11 @@
241223
::
242224
%'DELETE'
243225
~& > '%maat-api: DELETE'
226+
?. auth
227+
[(send [401 ~ [%plain "401 - Unauthorized"]]) state]
244228
?+ site [(send [404 ~ [%plain "404 - Not Found"]]) state]
245229
::
246230
[%apps %maat %api %lists @t ~]
247-
?. auth
248-
[(send [401 ~ [%plain "401 - Unauthorized"]]) state]
249231
=/ gid (snag 4 `(list @t)`site)
250232
=/ path /(scot %p our.bowl)/maat/(scot %da now.bowl)/[gid]/noun
251233
=, .^([=group =acl =reg =led] %gx path)
@@ -259,8 +241,6 @@
259241
state
260242
::
261243
[%apps %maat %api %lists @t %tasks @t ~]
262-
?. auth
263-
[(send [401 ~ [%plain "401 - Unauthorized"]]) state]
264244
~& > '%tahuti-api: DELETE /tasks/{tid}'
265245
=/ gid (snag 4 `(list @t)`site)
266246
=/ tid (snag 6 `(list @t)`site)
@@ -293,27 +273,7 @@
293273
(send [200 ~ [%plain "ok"]])
294274
[%pass ~ %agent [our.bowl %maat] %poke %maat-action !>(action)]
295275
state
296-
::
297276
==
298-
::
299-
::
300-
:: %'PATCH'
301-
:: ~& > '%maat-api: PATCH'
302-
:: ?+ site [(send [404 ~ [%plain "404 - Not Found"]]) state]
303-
:: ::
304-
:: [%apps %maat %api %lists @t %tasks @t ~]
305-
:: ?. auth
306-
:: [(send [401 ~ [%plain "401 - Unauthorized"]]) state]
307-
:: ~& > '%tahuti-api: PATCH /tasks/{tid}'
308-
:: =/ gid (snag 4 `(list @t)`site)
309-
:: =/ tid (snag 6 `(list @t)`site)
310-
:: =/ action [%upt-task gid tid]
311-
:: :- ^- (list card)
312-
:: %+ snoc
313-
:: (send [200 ~ [%plain "ok"]])
314-
:: [%pass ~ %agent [our.bowl %maat] %poke %maat-action !>(action)]
315-
:: state
316-
:: ==
317277
==
318278
--
319279
++ on-arvo

maat/app/maat-ui.hoon

+56-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
:: /- *maat
1+
/- *maat
22
/+ dbug
33
/+ verb
44
/+ default-agent
@@ -7,12 +7,15 @@
77
::
88
/* html-index %html /app/ui/html/index/html
99
/* html-tasks %html /app/ui/html/tasks/html
10+
/* html-tasks-public %html /app/ui/html/tasks-public/html
1011
/* html-create %html /app/ui/html/create/html
1112
/* html-invites %html /app/ui/html/invites/html
1213
/* html-invite %html /app/ui/html/invite/html
1314
/* html-settings %html /app/ui/html/settings/html
15+
/* html-about %html /app/ui/html/about/html
1416
/* html-edit-list %html /app/ui/html/edit-list/html
1517
/* html-edit-task %html /app/ui/html/edit-task/html
18+
/* html-show-task %html /app/ui/html/show-task/html
1619
/* css-udjat %css /app/ui/css/udjat/css
1720
/* css-style %css /app/ui/css/style/css
1821
/* svg-circles %svg /app/ui/svg/circles/svg
@@ -102,8 +105,27 @@
102105
=+ ext=ext.request-line
103106
=+ send=(cury response:schooner eyre-id)
104107
=+ auth=authenticated.inbound-request
105-
:: TODO:
106-
=/ public %.n
108+
=/ group=(unit group)
109+
?. (gte (lent site) 4)
110+
~
111+
=/ gid (snag 3 site)
112+
=/ path /(scot %p our.bowl)/maat/(scot %da now.bowl)/[gid]/noun
113+
=, .^([=group =acl =reg =led] %gx path)
114+
(some group)
115+
=/ public=?
116+
?^ group
117+
public:(need group)
118+
?~ ext
119+
%.n
120+
?+ +.ext %.n
121+
%css %.y
122+
%js %.y
123+
%ttf %.y
124+
%woff2 %.y
125+
%png %.y
126+
%svg %.y
127+
%json %.y
128+
==
107129
?. ?|(auth public)
108130
?. hx-req
109131
[(send [302 ~ [%login-redirect './apps/maat']]) state]
@@ -172,29 +194,40 @@
172194
:: html
173195
::
174196
[%apps %maat %lists @t %tasks @t %edit ~]
175-
[(send [200 ~ [%html html-edit-task]]) state]
197+
?: auth
198+
[(send [200 ~ [%html html-edit-task]]) state]
199+
?. hx-req
200+
[(send [302 ~ [%login-redirect './apps/maat']]) state]
201+
[(send [200 ~ [%hx-login-redirect './apps/maat']]) state]
202+
[%apps %maat %lists @t %tasks @t %show ~]
203+
[(send [200 ~ [%html html-show-task]]) state]
176204
[%apps %maat %lists @t @t ~]
177205
=/ endpoint (snag 4 `(list @t)`site)
178206
?+ endpoint [(send [404 ~ [%plain "404 - Not Found"]]) state]
179-
%tasks [(send [200 ~ [%html html-tasks]]) state]
180-
%settings [(send [200 ~ [%html html-settings]]) state]
181-
%edit [(send [200 ~ [%html html-edit-list]]) state]
182-
%invite [(send [200 ~ [%html html-invite]]) state]
183-
:: %settings
184-
:: ?: auth
185-
:: ?: .=(our.bowl host:(need group))
186-
:: [(send [200 ~ [%html html-settings-host]]) state]
187-
:: [(send [200 ~ [%html html-settings-member]]) state]
188-
:: [(send [200 ~ [%html html-settings-public]]) state]
189-
:: %about [(send [200 ~ [%html html-about]]) state]
190-
:: %invite
191-
:: ?. auth
192-
:: ?. hx-req
193-
:: [(send [302 ~ [%login-redirect './apps/tahuti']]) state]
194-
:: [(send [200 ~ [%hx-login-redirect './apps/tahuti']]) state]
195-
:: ?: public
196-
:: [(send [200 ~ [%html html-invite-public]]) state]
197-
:: [(send [200 ~ [%html html-invite]]) state]
207+
%tasks
208+
?: auth
209+
[(send [200 ~ [%html html-tasks]]) state]
210+
[(send [200 ~ [%html html-tasks-public]]) state]
211+
%settings
212+
?: auth
213+
[(send [200 ~ [%html html-settings]]) state]
214+
?. hx-req
215+
[(send [302 ~ [%login-redirect './apps/maat']]) state]
216+
[(send [200 ~ [%hx-login-redirect './apps/maat']]) state]
217+
%about
218+
[(send [200 ~ [%html html-about]]) state]
219+
%edit
220+
?: auth
221+
[(send [200 ~ [%html html-edit-list]]) state]
222+
?. hx-req
223+
[(send [302 ~ [%login-redirect './apps/maat']]) state]
224+
[(send [200 ~ [%hx-login-redirect './apps/maat']]) state]
225+
%invite
226+
?: auth
227+
[(send [200 ~ [%html html-invite]]) state]
228+
?. hx-req
229+
[(send [302 ~ [%login-redirect './apps/maat']]) state]
230+
[(send [200 ~ [%hx-login-redirect './apps/maat']]) state]
198231
==
199232
==
200233
--

test.sh

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
MAAT_ACCESS_CODE="$(pass talfus-laddus/code)"
2+
export TAHUTI_ACCESS_CODE
3+
export MAAT_ACCESS_CODE
4+
maat backup \
5+
--url https://ship.talfus-laddus.de \
6+
--gid 185acb93-8166-4447-94fe-c8ec7b2fdcce \
7+
--file "$HOME/.backup/maat-$(date -I).json"

tests/integration/test_invites.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ def test_put_invitees(zod, gid):
3434
assert response.status_code == 200
3535

3636

37-
def test_put_invitees_public(gid):
37+
@pytest.mark.usefixtures("list_public")
38+
def test_put_invitees_unauthorized_public(gid):
3839
"""Test PUT /invitees with unauthorized requests."""
3940
url = f"http://localhost:8080/apps/maat/api/lists/{gid}/invitees"
4041
response = requests.put(url, json={"invitee": "~nus"})
41-
assert response.status_code == 500
42+
assert response.status_code == 401
4243

4344

4445
def test_get_invites(nus, gid, list_, invitee_nus):
@@ -49,3 +50,10 @@ def test_get_invites(nus, gid, list_, invitee_nus):
4950
result = response.json()
5051
assert isinstance(result, list)
5152
assert list_ in result
53+
54+
55+
@pytest.mark.usefixtures("list_public")
56+
def test_get_invites_unauthorized_public():
57+
url = f"http://localhost:8080/apps/maat/api/invites"
58+
response = requests.get(url)
59+
assert response.status_code == 401

tests/integration/test_lists.py

+11-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from time import sleep
2-
import time
31
from uuid import uuid4
42

53
import pytest
@@ -64,6 +62,17 @@ def test_lists_put(zod, uuid):
6462
assert response.status_code == 200
6563

6664

65+
def test_lists_put_unauthorized(zod, uuid):
66+
list_ = {
67+
"gid": uuid,
68+
"title": "assembly",
69+
"public": False,
70+
}
71+
url = "http://localhost:8080/apps/maat/api/lists"
72+
response = requests.put(url, json=list_)
73+
assert response.status_code == 401
74+
75+
6776
def test_lists_get_all(zod, list_, lists_schema):
6877
# GET /lists
6978
url = "/apps/maat/api/lists"
@@ -138,21 +147,6 @@ def test_lists_update(zod, gid, list_):
138147
assert result == list_2
139148

140149

141-
# @pytest.mark.usefixtures("list_")
142-
# def test_lists_delete_unauthorized(zod, nus, gid):
143-
# # PUT
144-
# url = f"/apps/maat/api/lists/{gid}"
145-
# response = nus.delete(url)
146-
# assert response.status_code == 403
147-
148-
# # GET /lists
149-
# url = "/apps/maat/api/lists"
150-
# response = zod.get(url)
151-
# assert response.status_code == 200
152-
# result = response.json()
153-
# assert list in result
154-
155-
156150
@pytest.mark.usefixtures("list_")
157151
def test_lists_get_private(gid):
158152
# GET /lists/{uuid}

tests/integration/test_members.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,21 @@
33

44

55
@pytest.mark.usefixtures("list_")
6-
def test_put_members(zod, gid):
6+
def test_put_members_invalid(zod, gid):
7+
url = f"/apps/maat/api/list/{gid}/members"
8+
response = zod.put(url, json={})
9+
assert response.status_code == 404
10+
11+
12+
@pytest.mark.usefixtures("list_public")
13+
def test_put_members_public_unauthorized(zod, gid):
14+
url = f"http://localhost:8080/apps/maat/api/lists/{gid}/members"
15+
response = zod.put(url, json={})
16+
assert response.status_code == 404
17+
18+
19+
@pytest.mark.usefixtures("list_")
20+
def test_put_members_invalid(zod, gid):
721
url = f"/apps/maat/api/list/{gid}/members"
822
response = zod.put(url, json={})
923
assert response.status_code == 404

0 commit comments

Comments
 (0)