-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added DB migrations for workplaces, new roles to Keycloak and EPs to get, create and assign workplace. We still need to add EPs to list all members assigned to workplace. I will hopefully do it tomorrow, but I would appreciate review on the current code, in case there will be some obvious mistake and I would need to rewrite it :) --------- [anonymized]
- Loading branch information
1 parent
9eb01db
commit 0f2eaca
Showing
13 changed files
with
313 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
ALTER TABLE workplaces | ||
DROP COLUMN chairperson_id, | ||
ADD COLUMN email TEXT NOT NULL; | ||
|
||
COMMENT ON COLUMN workplaces.email IS 'Email that was created for the workplace in our mail server'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CREATE TABLE members_workplaces | ||
( member_id UUID NOT NULL REFERENCES members(id) | ||
, workplace_id UUID NOT NULL REFERENCES workplaces(id) | ||
, PRIMARY KEY (member_id, workplace_id) | ||
); | ||
|
||
COMMENT ON TABLE members_workplaces IS 'Members Workplaces is junction table for Many-to-Many relation between members and workplaces'; |
2 changes: 2 additions & 0 deletions
2
gray-whale/migrations/V20__permissions_for_member_workplace.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-- Grant permissions for new table | ||
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE members_workplaces TO orca; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
use chrono::{DateTime, Utc}; | ||
use rocket::serde::json::Json; | ||
use rocket::{Route, State}; | ||
use rocket_validation::{Validate, Validated}; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::api::members::Summary; | ||
use crate::api::Response; | ||
use crate::data::{Id, Workplace}; | ||
use crate::db::DbPool; | ||
use crate::server::oid::{JwtToken, Provider, Role}; | ||
|
||
use super::SuccessResponse; | ||
use uuid::Uuid; | ||
|
||
pub mod query; | ||
|
||
#[derive(Debug, Serialize, sqlx::FromRow)] | ||
pub struct WorkplaceSummary { | ||
id: Id<Workplace>, | ||
name: String, | ||
email: String, | ||
created_at: DateTime<Utc>, | ||
} | ||
|
||
#[get("/")] | ||
async fn list_all<'r>( | ||
db_pool: &State<DbPool>, | ||
oid_provider: &State<Provider>, | ||
token: JwtToken<'r>, | ||
) -> Response<Json<Vec<WorkplaceSummary>>> { | ||
oid_provider.require_role(&token, Role::ListWorkplaces)?; | ||
|
||
let summaries = query::list_summaries().fetch_all(db_pool.inner()).await?; | ||
|
||
Ok(Json(summaries)) | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize, Validate)] | ||
pub struct NewWorkplace { | ||
#[validate(required)] | ||
name: Option<String>, | ||
#[validate(required)] | ||
email: Option<String>, | ||
} | ||
|
||
#[post("/", format = "json", data = "<new_workplace>")] | ||
async fn create_workplace<'r>( | ||
db_pool: &State<DbPool>, | ||
oid_provider: &State<Provider>, | ||
token: JwtToken<'r>, | ||
new_workplace: Validated<Json<NewWorkplace>>, | ||
) -> Response<Json<WorkplaceSummary>> { | ||
oid_provider.require_role(&token, Role::ManageWorkplaces)?; | ||
|
||
// Create new workplace | ||
let workplace = query::create_workplace(&new_workplace.into_inner().into_inner()) | ||
.fetch_one(db_pool.inner()) | ||
.await?; | ||
|
||
Ok(Json(workplace)) | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct NewWorkplaceMember { | ||
member_id: Uuid, | ||
} | ||
|
||
#[post("/<workplace_id>", format = "json", data = "<new_workplace_member>")] | ||
async fn assign_member_to_workplace<'r>( | ||
db_pool: &State<DbPool>, | ||
oid_provider: &State<Provider>, | ||
token: JwtToken<'r>, | ||
workplace_id: Id<Workplace>, | ||
new_workplace_member: Json<NewWorkplaceMember>, | ||
) -> Response<SuccessResponse> { | ||
oid_provider.require_role(&token, Role::ManageWorkplaces)?; | ||
|
||
// Create new connection | ||
query::create_connection_between_member_and_workplace( | ||
workplace_id, | ||
new_workplace_member.into_inner().member_id, | ||
) | ||
.execute(db_pool.inner()) | ||
.await?; | ||
|
||
Ok(SuccessResponse::Accepted) | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct RemovedWorkplaceMember { | ||
member_id: Uuid, | ||
} | ||
|
||
#[delete( | ||
"/<workplace_id>", | ||
format = "json", | ||
data = "<removed_workplace_member>" | ||
)] | ||
async fn remove_member_from_workplace<'r>( | ||
db_pool: &State<DbPool>, | ||
oid_provider: &State<Provider>, | ||
token: JwtToken<'r>, | ||
workplace_id: Id<Workplace>, | ||
removed_workplace_member: Json<RemovedWorkplaceMember>, | ||
) -> Response<SuccessResponse> { | ||
oid_provider.require_role(&token, Role::ManageWorkplaces)?; | ||
|
||
// Remove existing connection | ||
query::remove_connection_between_member_and_workplace( | ||
workplace_id, | ||
removed_workplace_member.into_inner().member_id, | ||
) | ||
.execute(db_pool.inner()) | ||
.await?; | ||
|
||
Ok(SuccessResponse::Accepted) | ||
} | ||
|
||
#[get("/<workplace_id>")] | ||
async fn get_all_workplace_members<'r>( | ||
db_pool: &State<DbPool>, | ||
oid_provider: &State<Provider>, | ||
token: JwtToken<'r>, | ||
workplace_id: Id<Workplace>, | ||
) -> Response<Json<Vec<Summary>>> { | ||
oid_provider.require_role(&token, Role::ListWorkplaces)?; | ||
oid_provider.require_role(&token, Role::ListMembers)?; | ||
|
||
let summaries = query::get_all_workplace_members(workplace_id) | ||
.fetch_all(db_pool.inner()) | ||
.await?; | ||
|
||
Ok(Json(summaries)) | ||
} | ||
|
||
pub fn routes() -> Vec<Route> { | ||
routes![ | ||
list_all, | ||
create_workplace, | ||
assign_member_to_workplace, | ||
remove_member_from_workplace, | ||
get_all_workplace_members, | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
use uuid::Uuid; | ||
|
||
use super::{NewWorkplace, WorkplaceSummary}; | ||
use crate::api::members::Summary; | ||
use crate::data::{Id, Workplace}; | ||
use crate::db::{Query, QueryAs}; | ||
|
||
pub fn list_summaries() -> QueryAs<'static, WorkplaceSummary> { | ||
sqlx::query_as( | ||
" | ||
SELECT id | ||
, name | ||
, created_at | ||
FROM workplaces | ||
ORDER BY created_at DESC | ||
", | ||
) | ||
} | ||
|
||
pub fn create_workplace(new_workplace: &NewWorkplace) -> QueryAs<'_, WorkplaceSummary> { | ||
sqlx::query_as( | ||
" | ||
INSERT INTO workplaces | ||
( name | ||
) | ||
VALUES | ||
( $1, $2 ) | ||
RETURNING id | ||
, name | ||
, created_at | ||
", | ||
) | ||
.bind(&new_workplace.name) | ||
.bind(&new_workplace.email) | ||
} | ||
|
||
pub fn create_connection_between_member_and_workplace<'a>( | ||
workplace_id: Id<Workplace>, | ||
member_id: Uuid, | ||
) -> Query<'a> { | ||
sqlx::query( | ||
" | ||
INSERT INTO members_workplaces | ||
( workplace_id | ||
, member_id | ||
) | ||
VALUES | ||
( $1, $2 ) | ||
", | ||
) | ||
.bind(workplace_id) | ||
.bind(member_id) | ||
} | ||
|
||
pub fn remove_connection_between_member_and_workplace<'a>( | ||
workplace_id: Id<Workplace>, | ||
member_id: Uuid, | ||
) -> Query<'a> { | ||
sqlx::query( | ||
" | ||
DELETE FROM members_workplaces | ||
WHERE | ||
workplace_id=$1 AND member_id=$2 | ||
", | ||
) | ||
.bind(workplace_id) | ||
.bind(member_id) | ||
} | ||
|
||
pub fn get_all_workplace_members<'a>(workplace_id: Id<Workplace>) -> QueryAs<'a, Summary> { | ||
sqlx::query_as( | ||
" | ||
SELECT m.id | ||
, m.member_number | ||
, m.first_name | ||
, m.last_name | ||
, m.email | ||
, m.note | ||
, m.phone_number | ||
, m.city | ||
, m.left_at | ||
, array_agg(o.company_name ORDER BY o.created_at DESC) AS company_names | ||
, m.created_at | ||
FROM members_current AS m | ||
LEFT JOIN occupations o ON o.member_id = m.id | ||
LEFT JOIN members_workplaces mw ON mw.member_id = m.id | ||
WHERE mw.workplace_id = $1 | ||
GROUP BY m.id | ||
, m.member_number | ||
, m.first_name | ||
, m.last_name | ||
, m.email | ||
, m.phone_number | ||
, m.note | ||
, m.city | ||
, m.left_at | ||
, m.created_at | ||
ORDER BY m.member_number DESC | ||
", | ||
) | ||
.bind(workplace_id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.