]> Untitled Git - lemmy.git/blob - crates/api_crud/src/site/read.rs
Don't drop error context when adding a message to errors (#1958)
[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   blocking,
5   build_federated_instances,
6   get_local_user_settings_view_from_jwt_opt,
7   person::Register,
8   site::*,
9 };
10 use lemmy_db_views::site_view::SiteView;
11 use lemmy_db_views_actor::{
12   community_block_view::CommunityBlockView,
13   community_follower_view::CommunityFollowerView,
14   community_moderator_view::CommunityModeratorView,
15   person_block_view::PersonBlockView,
16   person_view::PersonViewSafe,
17 };
18 use lemmy_utils::{version, ConnectionId, LemmyError};
19 use lemmy_websocket::{messages::GetUsersOnline, LemmyContext};
20 use tracing::info;
21
22 #[async_trait::async_trait(?Send)]
23 impl PerformCrud for GetSite {
24   type Response = GetSiteResponse;
25
26   #[tracing::instrument(skip(context, websocket_id))]
27   async fn perform(
28     &self,
29     context: &Data<LemmyContext>,
30     websocket_id: Option<ConnectionId>,
31   ) -> Result<GetSiteResponse, LemmyError> {
32     let data: &GetSite = self;
33
34     let site_view = match blocking(context.pool(), SiteView::read).await? {
35       Ok(site_view) => Some(site_view),
36       // If the site isn't created yet, check the setup
37       Err(_) => {
38         if let Some(setup) = context.settings().setup.as_ref() {
39           let register = Register {
40             username: setup.admin_username.to_owned(),
41             email: setup.admin_email.clone().map(|s| s.into()),
42             password: setup.admin_password.clone().into(),
43             password_verify: setup.admin_password.clone().into(),
44             show_nsfw: true,
45             captcha_uuid: None,
46             captcha_answer: None,
47             honeypot: None,
48           };
49           let login_response = register.perform(context, websocket_id).await?;
50           info!("Admin {} created", setup.admin_username);
51
52           let create_site = CreateSite {
53             name: setup.site_name.to_owned(),
54             sidebar: setup.sidebar.to_owned(),
55             description: setup.description.to_owned(),
56             icon: setup.icon.to_owned(),
57             banner: setup.banner.to_owned(),
58             enable_downvotes: setup.enable_downvotes,
59             open_registration: setup.open_registration,
60             enable_nsfw: setup.enable_nsfw,
61             community_creation_admin_only: setup.community_creation_admin_only,
62             auth: login_response.jwt,
63           };
64           create_site.perform(context, websocket_id).await?;
65           info!("Site {} created", setup.site_name);
66           Some(blocking(context.pool(), SiteView::read).await??)
67         } else {
68           None
69         }
70       }
71     };
72
73     let mut admins = blocking(context.pool(), PersonViewSafe::admins).await??;
74
75     // Make sure the site creator is the top admin
76     if let Some(site_view) = site_view.to_owned() {
77       let site_creator_id = site_view.creator.id;
78       // TODO investigate why this is sometimes coming back null
79       // Maybe user_.admin isn't being set to true?
80       if let Some(creator_index) = admins.iter().position(|r| r.person.id == site_creator_id) {
81         let creator_person = admins.remove(creator_index);
82         admins.insert(0, creator_person);
83       }
84     }
85
86     let banned = blocking(context.pool(), PersonViewSafe::banned).await??;
87
88     let online = context
89       .chat_server()
90       .send(GetUsersOnline)
91       .await
92       .unwrap_or(1);
93
94     // Build the local user
95     let my_user = if let Some(local_user_view) = get_local_user_settings_view_from_jwt_opt(
96       data.auth.as_ref(),
97       context.pool(),
98       context.secret(),
99     )
100     .await?
101     {
102       let person_id = local_user_view.person.id;
103       let follows = blocking(context.pool(), move |conn| {
104         CommunityFollowerView::for_person(conn, person_id)
105       })
106       .await?
107       .map_err(LemmyError::from)
108       .map_err(|e| e.with_message("system_err_login"))?;
109
110       let person_id = local_user_view.person.id;
111       let community_blocks = blocking(context.pool(), move |conn| {
112         CommunityBlockView::for_person(conn, person_id)
113       })
114       .await?
115       .map_err(LemmyError::from)
116       .map_err(|e| e.with_message("system_err_login"))?;
117
118       let person_id = local_user_view.person.id;
119       let person_blocks = blocking(context.pool(), move |conn| {
120         PersonBlockView::for_person(conn, person_id)
121       })
122       .await?
123       .map_err(LemmyError::from)
124       .map_err(|e| e.with_message("system_err_login"))?;
125
126       let moderates = blocking(context.pool(), move |conn| {
127         CommunityModeratorView::for_person(conn, person_id)
128       })
129       .await?
130       .map_err(LemmyError::from)
131       .map_err(|e| e.with_message("system_err_login"))?;
132
133       Some(MyUserInfo {
134         local_user_view,
135         follows,
136         moderates,
137         community_blocks,
138         person_blocks,
139       })
140     } else {
141       None
142     };
143
144     let federated_instances = build_federated_instances(
145       context.pool(),
146       &context.settings().federation,
147       &context.settings().hostname,
148     )
149     .await?;
150
151     Ok(GetSiteResponse {
152       site_view,
153       admins,
154       banned,
155       online,
156       version: version::VERSION.to_string(),
157       my_user,
158       federated_instances,
159     })
160   }
161 }