8
8
from sqlalchemy .exc import SQLAlchemyError
9
9
from sqlalchemy .orm import Session
10
10
from sqlalchemy .orm .exc import MultipleResultsFound , NoResultFound
11
+ from sqlalchemy .sql .elements import Null
11
12
from starlette import status
12
13
from starlette .responses import RedirectResponse , Response
13
14
from starlette .templating import _TemplateResponse
22
23
)
23
24
from app .internal import comment as cmt
24
25
from app .internal .emotion import get_emotion
26
+ from app .internal .privacy import PrivacyKinds
25
27
from app .internal .utils import create_model , get_current_user
26
28
from app .routers .categories import get_user_categories
27
29
28
-
29
30
EVENT_DATA = Tuple [Event , List [Dict [str , str ]], str ]
30
31
TIME_FORMAT = "%Y-%m-%d %H:%M"
31
32
START_FORMAT = "%A, %d/%m/%Y %H:%M"
@@ -82,13 +83,20 @@ async def create_event_api(event: EventModel, session=Depends(get_db)):
82
83
83
84
@router .get ("/edit" , include_in_schema = False )
84
85
@router .get ("/edit" )
85
- async def eventedit (request : Request ,
86
- db_session : Session = Depends (get_db )) -> Response :
87
- user_id = 1 # until issue#29 will get current user_id from session
86
+ async def eventedit (
87
+ request : Request ,
88
+ db_session : Session = Depends (get_db ),
89
+ ) -> Response :
90
+ user_id = 1 # until issue#29 will get current user_id from session
88
91
categories_list = get_user_categories (db_session , user_id )
89
- return templates .TemplateResponse ("eventedit.html" ,
90
- {"request" : request ,
91
- "categories_list" : categories_list })
92
+ return templates .TemplateResponse (
93
+ "eventedit.html" ,
94
+ {
95
+ "request" : request ,
96
+ "categories_list" : categories_list ,
97
+ "privacy" : PrivacyKinds ,
98
+ },
99
+ )
92
100
93
101
94
102
@router .post ("/edit" , include_in_schema = False )
@@ -111,8 +119,11 @@ async def create_new_event(
111
119
112
120
vc_link = data ["vc_link" ]
113
121
category_id = data .get ("category_id" )
122
+ privacy = data ["privacy" ]
123
+ privacy_kinds = [kind .name for kind in PrivacyKinds ]
124
+ if privacy not in privacy_kinds :
125
+ privacy = PrivacyKinds .Public .name
114
126
is_google_event = data .get ("is_google_event" , "True" ) == "True"
115
-
116
127
invited_emails = get_invited_emails (data ["invited" ])
117
128
uninvited_contacts = get_uninvited_regular_emails (
118
129
session ,
@@ -129,25 +140,35 @@ async def create_new_event(
129
140
title = title ,
130
141
start = start ,
131
142
end = end ,
132
- owner_id = owner_id ,
133
143
all_day = all_day ,
144
+ owner_id = owner_id ,
134
145
content = content ,
135
146
location = location ,
136
147
vc_link = vc_link ,
137
148
invitees = invited_emails ,
138
149
category_id = category_id ,
139
150
availability = availability ,
140
151
is_google_event = is_google_event ,
152
+ privacy = privacy ,
141
153
)
142
154
143
155
messages = get_messages (session , event , uninvited_contacts )
144
156
return RedirectResponse (
145
157
router .url_path_for ("eventview" , event_id = event .id )
146
- + f'messages={ "---" .join (messages )} ' ,
158
+ + f'? messages={ "---" .join (messages )} ' ,
147
159
status_code = status .HTTP_302_FOUND ,
148
160
)
149
161
150
162
163
+ def raise_for_nonexisting_event (event_id : int ) -> None :
164
+ error_message = f"Event ID does not exist. ID: { event_id } "
165
+ logger .exception (error_message )
166
+ raise HTTPException (
167
+ status_code = status .HTTP_404_NOT_FOUND ,
168
+ detail = error_message ,
169
+ )
170
+
171
+
151
172
@router .get ("/{event_id}" , include_in_schema = False )
152
173
async def eventview (
153
174
request : Request ,
@@ -159,12 +180,15 @@ async def eventview(
159
180
if event .all_day :
160
181
start_format = "%A, %d/%m/%Y"
161
182
end_format = ""
183
+ event_considering_privacy = event_to_show (event , db )
184
+ if not event_considering_privacy :
185
+ raise_for_nonexisting_event (event .id )
162
186
messages = request .query_params .get ("messages" , "" ).split ("---" )
163
187
return templates .TemplateResponse (
164
188
"eventview.html" ,
165
189
{
166
190
"request" : request ,
167
- "event" : event ,
191
+ "event" : event_considering_privacy ,
168
192
"comments" : comments ,
169
193
"start_format" : start_format ,
170
194
"end_format" : end_format ,
@@ -173,6 +197,46 @@ async def eventview(
173
197
)
174
198
175
199
200
+ def check_event_owner (
201
+ event : Event ,
202
+ session : Depends (get_db ),
203
+ user : Optional [User ] = None ,
204
+ ) -> bool :
205
+ # TODO use current_user after user system merge
206
+ if not user :
207
+ user = get_current_user (session )
208
+ is_owner = event .owner_id == user .id
209
+ return is_owner
210
+
211
+
212
+ def event_to_show (
213
+ event : Event ,
214
+ session : Depends (get_db ),
215
+ user : Optional [User ] = None ,
216
+ ) -> Optional [Event ]:
217
+ """Check the given event's privacy and return
218
+ event/fixed private event/ nothing (hidden) accordingly"""
219
+ is_owner = check_event_owner (event , session , user )
220
+ if event .privacy == PrivacyKinds .Private .name and not is_owner :
221
+ event_dict = event .__dict__ .copy ()
222
+ if event_dict .get ("_sa_instance_state" , None ):
223
+ event_dict .pop ("_sa_instance_state" )
224
+ event_dict .pop ("id" )
225
+ private_event = Event (** event_dict )
226
+ private_event .title = PrivacyKinds .Private .name
227
+ private_event .content = PrivacyKinds .Private .name
228
+ private_event .location = PrivacyKinds .Private .name
229
+ private_event .color = Null
230
+ private_event .invitees = PrivacyKinds .Private .name
231
+ private_event .category_id = Null
232
+ private_event .emotion = Null
233
+ return private_event
234
+ elif event .privacy == PrivacyKinds .Hidden .name and not is_owner :
235
+ return
236
+ elif event .privacy == PrivacyKinds .Public .name or is_owner :
237
+ return event
238
+
239
+
176
240
@router .post ("/{event_id}/owner" )
177
241
async def change_owner (
178
242
request : Request ,
@@ -220,12 +284,7 @@ def by_id(db: Session, event_id: int) -> Event:
220
284
try :
221
285
event = db .query (Event ).filter_by (id = event_id ).one ()
222
286
except NoResultFound :
223
- error_message = f"Event ID does not exist. ID: { event_id } "
224
- logger .exception (error_message )
225
- raise HTTPException (
226
- status_code = status .HTTP_404_NOT_FOUND ,
227
- detail = error_message ,
228
- )
287
+ raise_for_nonexisting_event (event_id )
229
288
except MultipleResultsFound :
230
289
error_message = (
231
290
f"Multiple results found when getting event. Expected only one. "
@@ -337,6 +396,7 @@ def create_event(
337
396
category_id : Optional [int ] = None ,
338
397
availability : bool = True ,
339
398
is_google_event : bool = False ,
399
+ privacy : str = PrivacyKinds .Public .name ,
340
400
):
341
401
"""Creates an event and an association."""
342
402
@@ -348,6 +408,7 @@ def create_event(
348
408
title = title ,
349
409
start = start ,
350
410
end = end ,
411
+ privacy = privacy ,
351
412
content = content ,
352
413
owner_id = owner_id ,
353
414
location = location ,
0 commit comments