JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Add users table

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨9f36e3f

Showing ⁨⁨6⁩ changed files⁩ with ⁨⁨135⁩ insertions⁩ and ⁨⁨20⁩ deletions⁩

migrations/20230829104151_create_users.sql

View file
@@ -0,0 +1,13 @@
1 -- Add migration script here
2
3 CREATE TABLE IF NOT EXISTS users
4 (
5 username TEXT NOT NULL,
6 display_name TEXT,
7 image_url TEXT NOT NULL,
8 bio TEXT,
9 email TEXT,
10 password TEXT NOT NULL
11 )
12
13 CREATE UNIQUE INDEX unique_username ON users (username);
13 \ No newline at end of file

src/backend/git.rs

View file
@@ -309,8 +309,10 @@ impl RepositoryBackend for GitBackend {
309 309
310 310 async fn repository_info(
311 311 &mut self,
312 request: &RepositoryInfoRequest,
312 raw_request: &UserAuthenticated<RepositoryInfoRequest>,
313 313 ) -> Result<RepositoryView, Box<dyn Error + Send>> {
314 let request = raw_request.inner().await;
315
314 316 let repository = match self
315 317 .find_by_instance_username_name(
316 318 // &request.owner.instance.url,
@@ -323,16 +325,16 @@ impl RepositoryBackend for GitBackend {
323 325 Err(err) => return Err(Box::new(err)),
324 326 };
325 327
326 // if !repository.can_user_view_repository(
327 // request.owner.instance.url.as_str(),
328 // Some(request.owner.username.as_str()),
329 // ) {
330 // return Err(Box::new(GitBackendError::RepositoryNotFound {
331 // instance_url: request.owner.instance.url.clone(),
332 // username: request.owner.username.clone(),
333 // name: request.name.clone(),
334 // }));
335 // }
328 if !repository.can_user_view_repository(
329 request.owner.instance.url.as_str(),
330 Some(request.owner.username.as_str()),
331 ) {
332 return Err(Box::new(GitBackendError::RepositoryNotFound {
333 instance_url: request.owner.instance.url.clone(),
334 username: request.owner.username.clone(),
335 name: request.name.clone(),
336 }));
337 }
336 338
337 339 let git = match repository.open_git2_repository(&self.repository_folder) {
338 340 Ok(git) => git,

src/backend/mod.rs

View file
@@ -1,5 +1,6 @@
1 1 pub mod git;
2 2 pub mod github;
3 pub mod user;
3 4
4 5 use async_trait::async_trait;
5 6 use std::error::Error;
@@ -52,22 +53,27 @@ pub trait IssuesBackend {
52 53 ) -> Result<RepositoryIssuesResponse, Box<dyn Error + Send>>;
53 54 }
54 55
56 #[async_trait::async_trait]
55 57 pub trait AuthBackend {
56 fn register(&mut self, request: ()) -> Result<(), Box<dyn Error + Send>>;
58 async fn register(&mut self, request: ()) -> Result<(), Box<dyn Error + Send>>;
57 59
58 fn login(&mut self, request: ()) -> Result<(), Box<dyn Error + Send>>;
60 async fn login(&mut self, request: ()) -> Result<(), Box<dyn Error + Send>>;
59 61 }
60 62
61 pub trait UserBackend {
62 fn display_name(
63 #[async_trait::async_trait]
64 pub trait UserBackend: AuthBackend {
65 async fn display_name(
63 66 &mut self,
64 67 request: UserDisplayNameRequest,
65 68 ) -> Result<UserDisplayNameResponse, Box<dyn Error + Send>>;
66 69
67 fn display_image(
70 async fn display_image(
68 71 &mut self,
69 72 request: UserDisplayImageRequest,
70 73 ) -> Result<UserDisplayImageResponse, Box<dyn Error + Send>>;
71 74
72 fn bio(&mut self, request: UserBioRequest) -> Result<UserBioResponse, Box<dyn Error + Send>>;
75 async fn bio(
76 &mut self,
77 request: UserBioRequest,
78 ) -> Result<UserBioResponse, Box<dyn Error + Send>>;
73 79 }

src/backend/user.rs

View file
@@ -0,0 +1,89 @@
1 use std::error::Error;
2
3 use sqlx::PgPool;
4
5 use crate::messages::user::{
6 UserBioRequest, UserBioResponse, UserDisplayImageRequest, UserDisplayImageResponse,
7 UserDisplayNameRequest, UserDisplayNameResponse,
8 };
9
10 use super::{AuthBackend, UserBackend};
11
12 pub struct UserAuth {
13 pub pg_pool: PgPool,
14 }
15
16 impl UserAuth {
17 pub fn new(pool: PgPool) -> Self {
18 Self { pg_pool: pool }
19 }
20 }
21
22 #[async_trait::async_trait]
23 impl UserBackend for UserAuth {
24 async fn display_name(
25 &mut self,
26 request: UserDisplayNameRequest,
27 ) -> Result<UserDisplayNameResponse, Box<dyn std::error::Error + Send>> {
28 let db_row = sqlx::query_as!(
29 UserRow,
30 r#"SELECT * FROM users WHERE username = $1"#,
31 request.user.username
32 )
33 .await?;
34
35 Ok(UserDisplayNameResponse {
36 display_name: db_row.display_name,
37 })
38 }
39
40 async fn display_image(
41 &mut self,
42 request: UserDisplayImageRequest,
43 ) -> Result<UserDisplayImageResponse, Box<dyn std::error::Error + Send>> {
44 let db_row = sqlx::query_as!(
45 UserRow,
46 r#"SELECT * FROM users WHERE username = $1"#,
47 request.user.username
48 )
49 .await?;
50
51 Ok(UserDisplayImageResponse {
52 image_url: db_row.image_url,
53 })
54 }
55
56 async fn bio(
57 &mut self,
58 request: UserBioRequest,
59 ) -> Result<UserBioResponse, Box<dyn std::error::Error + Send>> {
60 let db_row = sqlx::query_as!(
61 UserRow,
62 r#"SELECT * FROM users WHERE username = $1"#,
63 request.user.username
64 )
65 .await?;
66
67 Ok(UserBioResponse { bio: db_row.bio })
68 }
69 }
70
71 #[async_trait::async_trait]
72 impl AuthBackend for UserAuth {
73 async fn register(&mut self, request: ()) -> Result<(), Box<dyn Error + Send>> {
74 todo!()
75 }
76
77 async fn login(&mut self, request: ()) -> Result<(), Box<dyn Error + Send>> {
78 todo!()
79 }
80 }
81
82 #[derive(Debug, sqlx::FromRow)]
83 struct UserRow {
84 pub username: String,
85 pub display_name: Option<String>,
86 pub bio: Option<String>,
87 pub email: Option<String>,
88 pub password: String,
89 }

src/connection.rs

View file
@@ -13,7 +13,7 @@ use tokio_tungstenite::{tungstenite::Message, WebSocketStream};
13 13
14 14 use crate::{
15 15 authentication::AuthenticationTokenGranter,
16 backend::{IssuesBackend, RepositoryBackend},
16 backend::{IssuesBackend, RepositoryBackend, UserBackend},
17 17 handshake::{HandshakeFinalize, HandshakeMessage, HandshakeResponse},
18 18 listener::Listeners,
19 19 messages::{
@@ -56,6 +56,7 @@ pub async fn connection_worker(
56 56 listeners: Arc<Mutex<Listeners>>,
57 57 connections: Arc<Mutex<Connections>>,
58 58 backend: Arc<Mutex<dyn RepositoryBackend + Send>>,
59 user_backend: Arc<Mutex<dyn UserBackend + Send>>,
59 60 auth_granter: Arc<Mutex<AuthenticationTokenGranter>>,
60 61 addr: SocketAddr,
61 62 ) {

src/main.rs

View file
@@ -3,7 +3,7 @@ use std::{error::Error, net::SocketAddr, sync::Arc};
3 3 use connection::{connection_worker, Connections, RawConnection};
4 4 use giterated_daemon::{
5 5 authentication::AuthenticationTokenGranter,
6 backend::{git::GitBackend, RepositoryBackend},
6 backend::{git::GitBackend, user::UserAuth, RepositoryBackend, UserBackend},
7 7 connection, listener,
8 8 };
9 9 use listener::Listeners;
@@ -47,7 +47,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
47 47
48 48 let repository_backend: Arc<Mutex<dyn RepositoryBackend + Send>> = Arc::new(Mutex::new({
49 49 let foo: GitBackend = GitBackend {
50 pg_pool: db_pool,
50 pg_pool: db_pool.clone(),
51 51 repository_folder: String::from(
52 52 config["repository"]["backend"]["git"]["root"]
53 53 .as_str()
@@ -57,6 +57,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
57 57 foo
58 58 }));
59 59
60 let user_backend: Arc<Mutex<dyn UserBackend + Send>> =
61 Arc::new(Mutex::new(UserAuth::new(db_pool)));
62
60 63 let token_granter = Arc::new(Mutex::new(AuthenticationTokenGranter {
61 64 config: config.clone(),
62 65 }));
@@ -98,6 +101,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
98 101 listeners.clone(),
99 102 connections.clone(),
100 103 repository_backend.clone(),
104 user_backend.clone(),
101 105 token_granter.clone(),
102 106 address,
103 107 )),