From 9a88397bb2eee70048b1bf3eec8f4ddef2881abf Mon Sep 17 00:00:00 2001 From: tom Date: Thu, 1 May 2025 19:42:33 +0200 Subject: [PATCH] added userLogout fixes #15, #10 --- Backend/endpoints/auto_logout.go | 6 +- .../{time_create.go => time-create.go} | 0 Backend/endpoints/{user.go => user-login.go} | 59 +++----------- Backend/endpoints/user-settings.go | 76 +++++++++++++++++++ Backend/models/booking.go | 9 ++- Backend/models/user.go | 32 ++++++-- Backend/models/workDay.go | 2 +- Backend/templates/pages.templ | 26 ++++--- Backend/templates/pages_templ.go | 8 +- Backend/templates/teamComponents.templ | 16 ++-- Backend/templates/teamComponents_templ.go | 6 +- 11 files changed, 151 insertions(+), 89 deletions(-) rename Backend/endpoints/{time_create.go => time-create.go} (100%) rename Backend/endpoints/{user.go => user-login.go} (58%) create mode 100644 Backend/endpoints/user-settings.go diff --git a/Backend/endpoints/auto_logout.go b/Backend/endpoints/auto_logout.go index b27f75f..32134a3 100644 --- a/Backend/endpoints/auto_logout.go +++ b/Backend/endpoints/auto_logout.go @@ -26,11 +26,11 @@ func autoLogout(w http.ResponseWriter) { } for _, user := range users { if user.CheckAnwesenheit() { - err = user.Logout() + err = user.CheckOut() if err != nil { fmt.Printf("Error logging out user %v\n", err) - }else { - logged_out_users = append(logged_out_users, user) + } else { + logged_out_users = append(logged_out_users, user) } } diff --git a/Backend/endpoints/time_create.go b/Backend/endpoints/time-create.go similarity index 100% rename from Backend/endpoints/time_create.go rename to Backend/endpoints/time-create.go diff --git a/Backend/endpoints/user.go b/Backend/endpoints/user-login.go similarity index 58% rename from Backend/endpoints/user.go rename to Backend/endpoints/user-login.go index 8681022..ee19238 100644 --- a/Backend/endpoints/user.go +++ b/Backend/endpoints/user-login.go @@ -4,6 +4,7 @@ import ( "arbeitszeitmessung/helper" "arbeitszeitmessung/models" "arbeitszeitmessung/templates" + "context" "log" "net/http" "strconv" @@ -34,22 +35,15 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) { } } -func UserSettingsHandler(w http.ResponseWriter, r *http.Request) { - helper.RequiresLogin(Session, w, r) - switch r.Method { - case http.MethodGet: - showUserPage(w, r, 0) - break - case http.MethodPost: - changePassword(w, r) - break - default: - http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed) - break - } -} - func showLoginPage(w http.ResponseWriter, r *http.Request, failed bool) { + r = r.WithContext(context.WithValue(r.Context(), "session", Session)) + if helper.GetEnv("GO_ENV", "production") == "debug" { + // http.Redirect(w, r, "/time", http.StatusSeeOther) + templates.LoginPage(failed).Render(r.Context(), w) + } + if Session.Exists(r.Context(), "user") { + http.Redirect(w, r, "/time", http.StatusSeeOther) + } templates.LoginPage(failed).Render(r.Context(), w) } @@ -91,38 +85,3 @@ func loginUser(w http.ResponseWriter, r *http.Request) { showLoginPage(w, r, false) return } - -// change user password and store salted hash in db -func changePassword(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() - if err != nil { - log.Println("Error parsing form!", err) - http.Error(w, "Error parsing form error", http.StatusBadRequest) - return - } - password := r.FormValue("password") - newPassword := r.FormValue("new_password") - if password == "" || newPassword == "" || newPassword != r.FormValue("new_password_repeat") { - showUserPage(w, r, http.StatusBadRequest) - return - } - user, err := (*models.User).GetByPersonalNummer(nil, Session.GetInt(r.Context(), "user")) - if err != nil { - log.Println("Error getting user!", err) - showUserPage(w, r, http.StatusBadRequest) - } - auth, err := user.ChangePass(password, newPassword) - if err != nil { - log.Println("Error when changing password!", err) - } - if auth { - showUserPage(w, r, http.StatusOK) - return - } - showUserPage(w, r, http.StatusUnauthorized) -} - -func showUserPage(w http.ResponseWriter, r *http.Request, status int) { - templates.UserPage(status).Render(r.Context(), w) - return -} diff --git a/Backend/endpoints/user-settings.go b/Backend/endpoints/user-settings.go new file mode 100644 index 0000000..7524f81 --- /dev/null +++ b/Backend/endpoints/user-settings.go @@ -0,0 +1,76 @@ +package endpoints + +import ( + "arbeitszeitmessung/helper" + "arbeitszeitmessung/models" + "arbeitszeitmessung/templates" + "log" + "net/http" +) + +func UserSettingsHandler(w http.ResponseWriter, r *http.Request) { + helper.RequiresLogin(Session, w, r) + switch r.Method { + case http.MethodGet: + showUserPage(w, r, 0) + break + case http.MethodPost: + switch r.FormValue("action") { + case "change-pass": + changePassword(w, r) + break + case "logout-user": + logoutUser(w, r) + break + } + + break + default: + http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed) + break + } +} + +// change user password and store salted hash in db +func changePassword(w http.ResponseWriter, r *http.Request) { + err := r.ParseForm() + if err != nil { + log.Println("Error parsing form!", err) + http.Error(w, "Error parsing form error", http.StatusBadRequest) + return + } + password := r.FormValue("password") + newPassword := r.FormValue("new_password") + if password == "" || newPassword == "" || newPassword != r.FormValue("new_password_repeat") { + showUserPage(w, r, http.StatusBadRequest) + return + } + user, err := (*models.User).GetByPersonalNummer(nil, Session.GetInt(r.Context(), "user")) + if err != nil { + log.Println("Error getting user!", err) + showUserPage(w, r, http.StatusBadRequest) + } + auth, err := user.ChangePass(password, newPassword) + if err != nil { + log.Println("Error when changing password!", err) + } + if auth { + showUserPage(w, r, http.StatusAccepted) + return + } + showUserPage(w, r, http.StatusUnauthorized) +} + +func logoutUser(w http.ResponseWriter, r *http.Request) { + + err := Session.Destroy(r.Context()) + if err != nil { + log.Println("Error destroying session!", err) + } + http.Redirect(w, r, "/user/login", http.StatusSeeOther) +} + +func showUserPage(w http.ResponseWriter, r *http.Request, status int) { + templates.UserPage(status).Render(r.Context(), w) + return +} diff --git a/Backend/models/booking.go b/Backend/models/booking.go index 0ac7313..47c2c47 100644 --- a/Backend/models/booking.go +++ b/Backend/models/booking.go @@ -47,8 +47,9 @@ func (b *Booking) FromUrlParams(params url.Values) Booking { return booking } -func (b Booking) Verify() bool { - if b.CardUID == "" || b.GeraetID == 0 || b.CheckInOut == 0 { +func (b *Booking) Verify() bool { + //check for overlapping time + arbeitszeit verstoß + if b.CardUID == "" { //|| b.GeraetID == 0 || b.CheckInOut == 0 { return false } return true @@ -71,7 +72,7 @@ func (b *Booking) Insert() error { func (b *Booking) InsertTimestamp() error { if b.Timestamp.IsZero() { - b.Timestamp = time.Now() + return b.Insert() } stmt, err := DB.Prepare((`INSERT INTO anwesenheit (card_uid, geraet_id, check_in_out, timestamp) VALUES ($1, $2, $3, $4) RETURNING counter_id`)) if err != nil { @@ -251,7 +252,9 @@ func (b *Booking) UpdateTime(newTime time.Time) { if b.CheckInOut == 254 { newBooking.CheckInOut = 4 } + log.Println("Updating") b.Update(newBooking) + b.Verify() b.Save() } diff --git a/Backend/models/user.go b/Backend/models/user.go index e5f5bd0..4be6b49 100644 --- a/Backend/models/user.go +++ b/Backend/models/user.go @@ -13,11 +13,11 @@ import ( ) type User struct { - CardUID string `json:"card_uid"` - Name string `json:"name"` - Vorname string `json:"vorname"` - PersonalNummer int `json:"personal_nummer"` - Arbeitszeit float32 `json:"arbeitszeit"` + CardUID string `json:"card_uid"` + Name string `json:"name"` + Vorname string `json:"vorname"` + PersonalNummer int `json:"personal_nummer"` + ArbeitszeitPerTag float32 `json:"arbeitszeit"` } func (u *User) GetUserFromSession(Session *scs.SessionManager, ctx context.Context) (User, error) { @@ -83,7 +83,7 @@ func (u *User) CheckAnwesenheit() bool { } // Creates a new booking for the user -> check_in_out will be 254 for automatic check out -func (u *User) Logout() error { +func (u *User) CheckOut() error { booking := (*Booking).New(nil, u.CardUID, 0, 254) err := booking.Insert() if err != nil { @@ -100,7 +100,7 @@ func (u *User) GetByPersonalNummer(personalNummer int) (User, error) { if err != nil { return user, err } - err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.Arbeitszeit) + err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.ArbeitszeitPerTag) if err != nil { return user, err @@ -196,7 +196,7 @@ func (u *User) GetNextWeek() WorkWeek { func parseUser(rows *sql.Rows) (User, error) { var user User - if err := rows.Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.Arbeitszeit); err != nil { + if err := rows.Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.ArbeitszeitPerTag); err != nil { log.Println("Error scanning row!", err) return user, err } @@ -228,6 +228,22 @@ func (u *User) GetLastSubmission() time.Time { return lastSub } +func (u *User) GetFromCardUID(card_uid string) (User, error) { + user := User{} + var err error + + qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag FROM personal_daten WHERE card_uid = $1;`)) + if err != nil { + return user, err + } + err = qStr.QueryRow(card_uid).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.ArbeitszeitPerTag) + + if err != nil { + return user, err + } + return user, nil +} + func getMonday(ts time.Time) time.Time { if ts.Weekday() != time.Monday { if ts.Weekday() == time.Sunday { diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go index 5ae237b..1e2a813 100644 --- a/Backend/models/workDay.go +++ b/Backend/models/workDay.go @@ -184,7 +184,7 @@ func (d *WorkDay) RequiresAction() bool { // returns a integer percentage of how much day has been worked of func (d *WorkDay) GetWorkDayProgress(user User) uint8 { - defaultWorkTime := time.Duration(user.Arbeitszeit * float32(time.Hour)) + defaultWorkTime := time.Duration(user.ArbeitszeitPerTag * float32(time.Hour)) progress := (d.workTime.Seconds() / defaultWorkTime.Seconds()) * 100 return uint8(progress) } diff --git a/Backend/templates/pages.templ b/Backend/templates/pages.templ index 0867308..6444e60 100644 --- a/Backend/templates/pages.templ +++ b/Backend/templates/pages.templ @@ -60,12 +60,21 @@ templ UserPage(status int) {

Aktuelles Passwort nicht korrekt!

case status >= 400:

Passwortwechsel fehlgeschlagen, bitte erneut versuchen!

- case status == 200: + case status == 202:

Passwortänderung erfolgreich

}
- + +
+ +
+

Nutzer abmelden

+
+

Nutzer von Weboberfläche abmelden.

+
+
+
@@ -123,18 +132,17 @@ templ TeamPresencePage(teamPresence map[bool][]models.User) {

Anwesend

- for _, user := range teamPresence[true] { - - @userPresenceComponent(user, true) - } + for _, user := range teamPresence[true] { + @userPresenceComponent(user, true) + }

Nicht Anwesend

- for _, user := range teamPresence[false] { - @userPresenceComponent(user, false) - } + for _, user := range teamPresence[false] { + @userPresenceComponent(user, false) + }
diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go index d93ac8d..06f3dcc 100644 --- a/Backend/templates/pages_templ.go +++ b/Backend/templates/pages_templ.go @@ -186,13 +186,13 @@ func UserPage(status int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - case status == 200: + case status == 202: templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

Passwortänderung erfolgreich

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

Nutzer abmelden

Nutzer von Weboberfläche abmelden.

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -238,7 +238,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 82, Col: 111} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 91, Col: 111} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -287,7 +287,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(userWeek.WeekStart.Format(time.DateOnly)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 95, Col: 85} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 109, Col: 85} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ index 9cebb77..1ab851f 100644 --- a/Backend/templates/teamComponents.templ +++ b/Backend/templates/teamComponents.templ @@ -34,7 +34,7 @@ templ employeComponent(week models.WorkWeek) { {{ year, kw := week.WeekStart.ISOWeek() }} -
+

{ week.User.Vorname } { week.User.Name }

Arbeitszeit

@@ -57,13 +57,13 @@ templ employeComponent(week models.WorkWeek) {
} -templ userPresenceComponent(user models.User, present bool){ +templ userPresenceComponent(user models.User, present bool) {
- if present { -
Anwesend
- } else { -
Abwesend
- } -

{user.Vorname} {user.Name}

+ if present { +
Anwesend
+ } else { +
Abwesend
+ } +

{ user.Vorname } { user.Name }

} diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go index 2a56f46..8ec9e88 100644 --- a/Backend/templates/teamComponents_templ.go +++ b/Backend/templates/teamComponents_templ.go @@ -154,7 +154,7 @@ func employeComponent(week models.WorkWeek) templ.Component { ctx = templ.ClearChildren(ctx) year, kw := week.WeekStart.ISOWeek() - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -293,7 +293,7 @@ func userPresenceComponent(user models.User, present bool) templ.Component { var templ_7745c5c3_Var16 string templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 67, Col: 17} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 67, Col: 19} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { @@ -306,7 +306,7 @@ func userPresenceComponent(user models.User, present bool) templ.Component { var templ_7745c5c3_Var17 string templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 67, Col: 29} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 67, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil {