]> Untitled Git - lemmy.git/blob - crates/api_crud/src/site/read.rs
Dont return error in case optional auth is invalid (#2879)
[lemmy.git] / crates / api_crud / src / site / read.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   context::LemmyContext,
5   sensitive::Sensitive,
6   site::{GetSite, GetSiteResponse, MyUserInfo},
7   utils::{check_user_valid, check_validator_time},
8   websocket::handlers::online_users::GetUsersOnline,
9 };
10 use lemmy_db_schema::{
11   newtypes::LocalUserId,
12   source::{
13     actor_language::{LocalUserLanguage, SiteLanguage},
14     language::Language,
15     tagline::Tagline,
16   },
17 };
18 use lemmy_db_views::structs::{CustomEmojiView, LocalUserView, SiteView};
19 use lemmy_db_views_actor::structs::{
20   CommunityBlockView,
21   CommunityFollowerView,
22   CommunityModeratorView,
23   PersonBlockView,
24   PersonView,
25 };
26 use lemmy_utils::{claims::Claims, error::LemmyError, version, ConnectionId};
27
28 #[async_trait::async_trait(?Send)]
29 impl PerformCrud for GetSite {
30   type Response = GetSiteResponse;
31
32   #[tracing::instrument(skip(context, _websocket_id))]
33   async fn perform(
34     &self,
35     context: &Data<LemmyContext>,
36     _websocket_id: Option<ConnectionId>,
37   ) -> Result<GetSiteResponse, LemmyError> {
38     let data: &GetSite = self;
39
40     let site_view = SiteView::read_local(context.pool()).await?;
41
42     let admins = PersonView::admins(context.pool()).await?;
43
44     let online = context.chat_server().send(GetUsersOnline).await?;
45
46     // Build the local user
47     let my_user = if let Some(local_user_view) =
48       local_user_settings_view_from_jwt_opt(data.auth.as_ref(), context).await
49     {
50       let person_id = local_user_view.person.id;
51       let local_user_id = local_user_view.local_user.id;
52
53       let follows = CommunityFollowerView::for_person(context.pool(), person_id)
54         .await
55         .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?;
56
57       let person_id = local_user_view.person.id;
58       let community_blocks = CommunityBlockView::for_person(context.pool(), person_id)
59         .await
60         .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?;
61
62       let person_id = local_user_view.person.id;
63       let person_blocks = PersonBlockView::for_person(context.pool(), person_id)
64         .await
65         .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?;
66
67       let moderates = CommunityModeratorView::for_person(context.pool(), person_id)
68         .await
69         .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?;
70
71       let discussion_languages = LocalUserLanguage::read(context.pool(), local_user_id)
72         .await
73         .map_err(|e| LemmyError::from_error_message(e, "system_err_login"))?;
74
75       Some(MyUserInfo {
76         local_user_view,
77         follows,
78         moderates,
79         community_blocks,
80         person_blocks,
81         discussion_languages,
82       })
83     } else {
84       None
85     };
86
87     let all_languages = Language::read_all(context.pool()).await?;
88     let discussion_languages = SiteLanguage::read_local_raw(context.pool()).await?;
89     let taglines = Tagline::get_all(context.pool(), site_view.local_site.id).await?;
90     let custom_emojis = CustomEmojiView::get_all(context.pool(), site_view.local_site.id).await?;
91
92     Ok(GetSiteResponse {
93       site_view,
94       admins,
95       online,
96       version: version::VERSION.to_string(),
97       my_user,
98       all_languages,
99       discussion_languages,
100       taglines,
101       custom_emojis,
102     })
103   }
104 }
105
106 #[tracing::instrument(skip_all)]
107 async fn local_user_settings_view_from_jwt_opt(
108   jwt: Option<&Sensitive<String>>,
109   context: &LemmyContext,
110 ) -> Option<LocalUserView> {
111   match jwt {
112     Some(jwt) => {
113       let claims = Claims::decode(jwt.as_ref(), &context.secret().jwt_secret)
114         .ok()?
115         .claims;
116       let local_user_id = LocalUserId(claims.sub);
117       let local_user_view = LocalUserView::read(context.pool(), local_user_id)
118         .await
119         .ok()?;
120       check_user_valid(
121         local_user_view.person.banned,
122         local_user_view.person.ban_expires,
123         local_user_view.person.deleted,
124       )
125       .ok()?;
126
127       check_validator_time(&local_user_view.local_user.validator_time, &claims).ok()?;
128
129       Some(local_user_view)
130     }
131     None => None,
132   }
133 }