Mobile support to come.
use async_trait::async_trait;
use crate::dto::{
GetCurrentUserRequest, GetUserRequest, HasUserRequest, ListUserRepositoriesRequest,
RepositoryResponse, UserResponse,
};
use crate::error::UserError;
use crate::repository::{
RepositoryRepository, RepositoryRepositoryImpl, UserRepository, UserRepositoryImpl,
};
use crate::util::auth::is_reserved_name;
#[async_trait]
pub trait UserService: Send + Sync + 'static {
async fn has_user(&self, request: HasUserRequest) -> Result<(), UserError>;
async fn get_current_user(
&self,
request: GetCurrentUserRequest,
) -> Result<UserResponse, UserError>;
async fn get_user(&self, request: GetUserRequest) -> Result<UserResponse, UserError>;
async fn list_repositories(
&self,
request: ListUserRepositoriesRequest,
) -> Result<Vec<RepositoryResponse>, UserError>;
}
#[derive(Debug, Clone)]
pub struct UserServiceImpl<U, R>
where
U: UserRepository,
R: RepositoryRepository,
{
user_repo: U,
repo_repo: R,
}
impl UserServiceImpl<UserRepositoryImpl, RepositoryRepositoryImpl> {
pub fn new(user_repo: UserRepositoryImpl, repo_repo: RepositoryRepositoryImpl) -> Self {
Self {
user_repo,
repo_repo,
}
}
}
#[async_trait]
impl<U, R> UserService for UserServiceImpl<U, R>
where
U: UserRepository,
R: RepositoryRepository,
{
async fn has_user(&self, request: HasUserRequest) -> Result<(), UserError> {
let name = request.name.to_string();
if is_reserved_name(&name) || self.user_repo.is_name_taken(&name).await? {
return Ok(());
}
Err(UserError::NotFound(name))
}
async fn get_current_user(
&self,
request: GetCurrentUserRequest,
) -> Result<UserResponse, UserError> {
let user = self
.user_repo
.get_by_id(request.user_id)
.await?
.ok_or_else(|| UserError::NotFound(request.user_id.to_string()))?;
Ok(user.into())
}
async fn get_user(&self, request: GetUserRequest) -> Result<UserResponse, UserError> {
let user_name = request.user_name.to_string();
let user = self
.user_repo
.get(&user_name)
.await?
.ok_or_else(|| UserError::NotFound(user_name))?;
Ok(user.into())
}
async fn list_repositories(
&self,
request: ListUserRepositoriesRequest,
) -> Result<Vec<RepositoryResponse>, UserError> {
let user_name = request.user_name.to_string();
let user = self
.user_repo
.get(&user_name)
.await?
.ok_or_else(|| UserError::NotFound(user_name.clone()))?;
let repositories = self.repo_repo.list_by_owner(&user_name).await?;
let is_owner = request.viewer_id.map(|id| id == user.id).unwrap_or(false);
let repositories = if is_owner {
repositories
} else {
repositories.into_iter().filter(|r| r.is_public()).collect()
};
Ok(repositories.into_iter().map(|r| r.into()).collect())
}
}
refactoring validate user -> hasUser and wiring up signup form
baepaul•3fea7211d ago
replaced create_user api with validate_name api
mikkel•0e0bf523d ago
created temporary signup page
mikkel•5a9138b3d ago
added reserved user names to avoid
mikkel•f0953d45d ago
implemented create user endpoint
mikkel•5b3ad656d ago
added /user endpoint
mike•b65ceb112d ago
added auth for list user repos api
mike•7bb088e12d ago
nits
mike•b040df512d ago
implemented get user and list user repos apis
mike•7ce056912d ago