diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 463e52e..0000000 --- a/TODO.md +++ /dev/null @@ -1,2 +0,0 @@ -- create new field in user table -> user\_token -- change in misc.rs personal calendar function on not require User, but user\_token diff --git a/migration.sql b/migration.sql index 7da1feb..ad652b5 100644 --- a/migration.sql +++ b/migration.sql @@ -17,7 +17,8 @@ CREATE TABLE IF NOT EXISTS "user" ( "phone" text, "address" text, "family_id" INTEGER REFERENCES family(id), - "membership_pdf" BLOB + "membership_pdf" BLOB, + "user_token" TEXT NOT NULL DEFAULT (lower(hex(randomblob(16)))) ); CREATE TABLE IF NOT EXISTS "family" ( diff --git a/src/model/family.rs b/src/model/family.rs index f648cfd..894b082 100644 --- a/src/model/family.rs +++ b/src/model/family.rs @@ -75,7 +75,7 @@ GROUP BY family.id;" } pub async fn members(&self, db: &SqlitePool) -> Vec { - sqlx::query_as!(User, "SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE family_id = ?", self.id) + sqlx::query_as!(User, "SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE family_id = ?", self.id) .fetch_all(db) .await .unwrap() diff --git a/src/model/rower.rs b/src/model/rower.rs index 7099cff..fd477b2 100644 --- a/src/model/rower.rs +++ b/src/model/rower.rs @@ -16,7 +16,7 @@ impl Rower { sqlx::query_as!( User, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE id in (SELECT rower_id FROM rower WHERE logbook_id=?) ", diff --git a/src/model/user.rs b/src/model/user.rs index d5f8a41..717596b 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -42,6 +42,7 @@ pub struct User { pub phone: Option, pub address: Option, pub family_id: Option, + pub user_token: String, } #[derive(Debug, Serialize, Deserialize)] @@ -493,7 +494,7 @@ ASKÖ Ruderverein Donau Linz", self.name), sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE id like ? ", @@ -508,7 +509,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE id like ? ", @@ -525,7 +526,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE lower(name)=? ", @@ -567,7 +568,7 @@ WHERE lower(name)=? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE deleted = 0 ORDER BY last_access DESC @@ -589,7 +590,7 @@ ORDER BY last_access DESC sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user u JOIN user_role ur ON u.id = ur.user_id WHERE ur.role_id = ? AND deleted = 0 @@ -605,14 +606,14 @@ ORDER BY name; sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE family_id IS NOT NULL GROUP BY family_id UNION -- Select users with a null family_id, without grouping -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE family_id IS NULL; " ) @@ -625,7 +626,7 @@ WHERE family_id IS NULL; sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE deleted = 0 AND dob != '' and weight != '' and sex != '' ORDER BY name @@ -640,7 +641,7 @@ ORDER BY name sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, user_token FROM user WHERE deleted = 0 AND (SELECT COUNT(*) FROM user_role WHERE user_id=user.id AND role_id = (SELECT id FROM role WHERE name = 'cox')) > 0 ORDER BY last_access DESC diff --git a/src/tera/misc.rs b/src/tera/misc.rs index 8f3e905..4d0e76e 100644 --- a/src/tera/misc.rs +++ b/src/tera/misc.rs @@ -9,10 +9,21 @@ async fn cal(db: &State) -> (ContentType, String) { (ContentType::Calendar, Event::get_ics_feed(db).await) } -#[get("/cal/registered")] -async fn cal_registered(db: &State, user: User) -> (ContentType, String) { - //TODO: add unit test once proper functionality is there - (ContentType::Calendar, get_personal_cal(db, &user).await) +#[get("/cal/personal//")] +async fn cal_registered( + db: &State, + user_id: i32, + uuid: &str, +) -> Result<(ContentType, String), String> { + let Some(user) = User::find_by_id(db, user_id).await else { + return Err("Invalid".into()); + }; + + if &user.user_token != uuid { + return Err("Invalid".into()); + } + + Ok((ContentType::Calendar, get_personal_cal(db, &user).await)) } pub fn routes() -> Vec { diff --git a/templates/index.html.tera b/templates/index.html.tera index 5d86b6d..3345425 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -220,9 +220,11 @@

Du möchtest immer up-to-date mit den Events und Ausfahrten bleiben? Wir bieten 3 verschiedene Arten von Kalender an:

    -
  1. Alle Events und Ausfahrten, zu denen du dich angemeldet hast: https://app.rudernlinz.at/cal/personal?my-secrect-key
  2. +
  3. Alle Events und Ausfahrten, zu denen du dich angemeldet hast: https://app.rudernlinz.at/cal/personal/{{ loggedin_user.id }}/{{ loggedin_user.user_token }}
    + Dieser Link enthält einen zufällig generierten Teil, damit nur du (und jene, denen du diesen Link weitergibst) Zugang zu diesen Daten hast.
  4. Allgemeiner Kalender, zB save-the-dates (Wanderfahrten, ...): https://rudernlinz.at/cal
  5. -
  6. Alle Events: https://app.rudernlinz.at/cal
  7. +
  8. Alle Events: https://app.rudernlinz.at/cal
    + Beachte, dass dieser Kalender keine Ausfahrten enthält, die von einzelnen Steuerpersonen augeschrieben werden. Dieser Kalender wird zB auf https://rudernlinz.at/termine verwendet und wir möchten keine persönlichen Daten (Namen etc.) leaken.
Du kannst die Kalender einfach in deinen Kalender als "externen Kalender" synchronisieren. Die genauen Schritte hängen von deiner verwendeten Software ab.