allow-admin-to-delete-logbook-entries #665

Merged
philipp merged 2 commits from allow-admin-to-delete-logbook-entries into staging 2024-08-12 20:56:08 +02:00
4 changed files with 62 additions and 40 deletions

2
fd
View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
scp read@128.140.64.118:/home/rowing/db.sqlite db.sqlite scp root@128.140.64.118:/home/rowing/db.sqlite db.sqlite
#sqlite3 db.sqlite < seeds.sql #sqlite3 db.sqlite < seeds.sql

View File

@ -699,46 +699,57 @@ ORDER BY departure DESC
pub async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), LogbookDeleteError> { pub async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), LogbookDeleteError> {
Log::create(db, format!("{} deleted trip: {self:?}", user.name)).await; Log::create(db, format!("{} deleted trip: {self:?}", user.name)).await;
if user.has_role(db, "admin").await if self.arrival.is_none() {
|| user.has_role(db, "Vorstand").await if user.has_role(db, "admin").await
|| user.id == self.shipmaster || user.has_role(db, "Vorstand").await
{ || user.id == self.shipmaster
let now = Local::now().naive_local(); {
let difference = now - self.departure; let now = Local::now().naive_local();
if difference > Duration::hours(1) { let difference = now - self.departure;
let vorstand = Role::find_by_name(db, "Vorstand").await.unwrap(); if difference > Duration::hours(1) {
let logbook = LogbookWithBoatAndRowers::from(db, self.clone()).await; let vorstand = Role::find_by_name(db, "Vorstand").await.unwrap();
let mut msg = format!("{} hat folgenden Logbuch-Eintrag jetzt gelöscht, welcher bereits vor über einer Stunde begonnen wurde: Schiffsführer: {}, Steuerperson: {}, Abfahrt: {}", user.name, logbook.steering_user.name, logbook.steering_user.name, logbook.logbook.departure.format("%Y-%m-%d %H:%M")); let logbook = LogbookWithBoatAndRowers::from(db, self.clone()).await;
if let Some(destination) = logbook.logbook.destination { let mut msg = format!("{} hat folgenden Logbuch-Eintrag jetzt gelöscht, welcher bereits vor über einer Stunde begonnen wurde: Schiffsführer: {}, Steuerperson: {}, Abfahrt: {}", user.name, logbook.steering_user.name, logbook.steering_user.name, logbook.logbook.departure.format("%Y-%m-%d %H:%M"));
msg.push_str(&format!(", Ziel: {}", destination)); if let Some(destination) = logbook.logbook.destination {
} else { msg.push_str(&format!(", Ziel: {}", destination));
msg.push_str(", kein Ziel eingegeben"); } else {
} msg.push_str(", kein Ziel eingegeben");
msg.push_str(", Ruderer: ");
let mut it = logbook.rowers.clone().into_iter().peekable();
while let Some(rower) = it.next() {
msg.push_str(&rower.name);
if it.peek().is_some() {
msg.push_str(" + ");
} }
msg.push_str(", Ruderer: ");
let mut it = logbook.rowers.clone().into_iter().peekable();
while let Some(rower) = it.next() {
msg.push_str(&rower.name);
if it.peek().is_some() {
msg.push_str(" + ");
}
}
Notification::create_for_role(
db,
&vorstand,
&msg,
"Ungewöhnliches Verhalten",
None,
None,
)
.await;
} }
Notification::create_for_role( sqlx::query!("DELETE FROM logbook WHERE id=?", self.id)
db, .execute(db)
&vorstand, .await
&msg, .unwrap(); //Okay, because we can only create a Logbook of a valid id
"Ungewöhnliches Verhalten", return Ok(());
None, }
None, } else {
) // Only admins can delete completed logbook entries
.await; if user.has_role(db, "admin").await {
sqlx::query!("DELETE FROM logbook WHERE id=?", self.id)
.execute(db)
.await
.unwrap(); //Okay, because we can only create a Logbook of a valid id
return Ok(());
} }
sqlx::query!("DELETE FROM logbook WHERE id=?", self.id)
.execute(db)
.await
.unwrap(); //Okay, because we can only create a Logbook of a valid id
return Ok(());
} }
Err(LogbookDeleteError::NotYourEntry) Err(LogbookDeleteError::NotYourEntry)
} }

View File

@ -400,6 +400,11 @@ async fn home(
async fn delete(db: &State<SqlitePool>, logbook_id: i64, user: DonauLinzUser) -> Flash<Redirect> { async fn delete(db: &State<SqlitePool>, logbook_id: i64, user: DonauLinzUser) -> Flash<Redirect> {
let logbook = Logbook::find_by_id(db, logbook_id).await; let logbook = Logbook::find_by_id(db, logbook_id).await;
if let Some(logbook) = logbook { if let Some(logbook) = logbook {
let redirect = if logbook.arrival.is_some() {
"/log/show"
} else {
"/log"
};
Log::create( Log::create(
db, db,
format!("User {} tries to delete log entry {logbook_id}", &user.name), format!("User {} tries to delete log entry {logbook_id}", &user.name),
@ -407,11 +412,11 @@ async fn delete(db: &State<SqlitePool>, logbook_id: i64, user: DonauLinzUser) ->
.await; .await;
match logbook.delete(db, &user).await { match logbook.delete(db, &user).await {
Ok(_) => Flash::success( Ok(_) => Flash::success(
Redirect::to("/log"), Redirect::to(redirect),
format!("Eintrag {} gelöscht!", logbook_id), format!("Eintrag {} von {} gelöscht!", logbook_id, user.name),
), ),
Err(LogbookDeleteError::NotYourEntry) => Flash::error( Err(LogbookDeleteError::NotYourEntry) => Flash::error(
Redirect::to("/log"), Redirect::to(redirect),
"Du hast nicht die Berechtigung, den Eintrag zu löschen!", "Du hast nicht die Berechtigung, den Eintrag zu löschen!",
), ),
} }

View File

@ -262,6 +262,12 @@
<input type="hidden" name="logtype" value="{{ log.logtype }}" /> <input type="hidden" name="logtype" value="{{ log.logtype }}" />
<input type="submit" value="Updaten" /> <input type="submit" value="Updaten" />
</form> </form>
<a href="/log/{{ log.id }}/delete"
class="w-28 btn btn-alert"
onclick="return confirm('Willst du diesen Logbucheintrag wirklich löschen?');">
{% include "includes/delete-icon" %}
Löschen
</a>
{% endif %} {% endif %}
</details> </details>
</div> </div>