feat: Create unique index for UserId and Target
All checks were successful
DCO checker / DCO checker (pull_request) Successful in 4s
Rust CI / Rust CI (pull_request) Successful in 4m32s

Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb 2024-07-17 23:22:24 +03:00
parent 9c1ba97791
commit 868ec66b68
Signed by: awiteb
GPG key ID: 3F6B55640AA6682F
2 changed files with 64 additions and 31 deletions

View file

@ -139,30 +139,38 @@ impl UsersStatusExt for DatabaseConnection {
whitelister: &UserModel, whitelister: &UserModel,
target_public_key: &PublicKey, target_public_key: &PublicKey,
) -> ServerResult<()> { ) -> ServerResult<()> {
if self.is_whitelisted(whitelister, target_public_key).await? {
return Err(WsError::AlreadyOnTheWhitelist.into());
}
if whitelister.public_key == target_public_key.to_string() { if whitelister.public_key == target_public_key.to_string() {
return Err(WsError::CannotAddSelfToWhitelist.into()); return Err(WsError::CannotAddSelfToWhitelist.into());
} }
if let Some(mut user) = get_user_status(self, whitelister, target_public_key) if let Some(mut user) = get_user_status(
.await? self,
.map(IntoActiveModel::into_active_model) whitelister,
target_public_key,
AccessStatus::Blacklisted,
)
.await?
.map(IntoActiveModel::into_active_model)
{ {
user.status = Set(AccessStatus::Whitelisted); user.status = Set(AccessStatus::Whitelisted);
user.updated_at = Set(Utc::now()); user.updated_at = Set(Utc::now());
user.update(self).await?; user.update(self).await?;
} else { } else if let Err(err) = (UsersStatusActiveModel {
UsersStatusActiveModel { user_id: Set(whitelister.id),
user_id: Set(whitelister.id), target: Set(target_public_key.to_string()),
target: Set(target_public_key.to_string()), status: Set(AccessStatus::Whitelisted),
status: Set(AccessStatus::Whitelisted), updated_at: Set(Utc::now()),
updated_at: Set(Utc::now()), ..Default::default()
..Default::default() }
.save(self)
.await)
{
match err.sql_err() {
Some(SqlErr::UniqueConstraintViolation(_)) => {
return Err(WsError::AlreadyOnTheWhitelist.into());
}
_ => return Err(err.into()),
} }
.save(self)
.await?;
} }
Ok(()) Ok(())
@ -173,30 +181,38 @@ impl UsersStatusExt for DatabaseConnection {
blacklister: &UserModel, blacklister: &UserModel,
target_public_key: &PublicKey, target_public_key: &PublicKey,
) -> ServerResult<()> { ) -> ServerResult<()> {
if self.is_blacklisted(blacklister, target_public_key).await? {
return Err(WsError::AlreadyOnTheBlacklist.into());
}
if blacklister.public_key == target_public_key.to_string() { if blacklister.public_key == target_public_key.to_string() {
return Err(WsError::CannotAddSelfToBlacklist.into()); return Err(WsError::CannotAddSelfToBlacklist.into());
} }
if let Some(mut user) = get_user_status(self, blacklister, target_public_key) if let Some(mut user) = get_user_status(
.await? self,
.map(IntoActiveModel::into_active_model) blacklister,
target_public_key,
AccessStatus::Whitelisted,
)
.await?
.map(IntoActiveModel::into_active_model)
{ {
user.status = Set(AccessStatus::Blacklisted); user.status = Set(AccessStatus::Blacklisted);
user.updated_at = Set(Utc::now()); user.updated_at = Set(Utc::now());
user.update(self).await?; user.update(self).await?;
} else { } else if let Err(err) = (UsersStatusActiveModel {
UsersStatusActiveModel { user_id: Set(blacklister.id),
user_id: Set(blacklister.id), target: Set(target_public_key.to_string()),
target: Set(target_public_key.to_string()), status: Set(AccessStatus::Blacklisted),
status: Set(AccessStatus::Blacklisted), updated_at: Set(Utc::now()),
updated_at: Set(Utc::now()), ..Default::default()
..Default::default() }
.save(self)
.await)
{
match err.sql_err() {
Some(SqlErr::UniqueConstraintViolation(_)) => {
return Err(WsError::AlreadyOnTheBlacklist.into());
}
_ => return Err(err.into()),
} }
.save(self)
.await?;
} }
Ok(()) Ok(())
@ -278,9 +294,14 @@ async fn get_user_status(
conn: &DatabaseConnection, conn: &DatabaseConnection,
user: &UserModel, user: &UserModel,
target_public_key: &PublicKey, target_public_key: &PublicKey,
status: AccessStatus,
) -> ServerResult<Option<UsersStatusModel>> { ) -> ServerResult<Option<UsersStatusModel>> {
user.find_related(UsersStatusEntity) user.find_related(UsersStatusEntity)
.filter(UsersStatusColumn::Target.eq(target_public_key.to_string())) .filter(
UsersStatusColumn::Target
.eq(target_public_key.to_string())
.and(UsersStatusColumn::Status.eq(status)),
)
.one(conn) .one(conn)
.await .await
.map_err(Into::into) .map_err(Into::into)

View file

@ -40,6 +40,18 @@ impl MigrationTrait for Migration {
.to_owned(), .to_owned(),
) )
.await?; .await?;
manager
.create_index(
Index::create()
.if_not_exists()
.name("sep_status")
.table(UsersStatus::Table)
.col(UsersStatus::UserId)
.col(UsersStatus::Target)
.unique()
.to_owned(),
)
.await?;
manager manager
.create_table( .create_table(