package Auth import ( "database/sql/driver" "encoding/json" "net/http" "time" "git.tovijaeschke.xyz/tovi/Envelope/Backend/Database" "git.tovijaeschke.xyz/tovi/Envelope/Backend/Models" ) type credentials struct { Username string `json:"username"` Password string `json:"password"` } type loginResponse struct { Status string `json:"status"` Message string `json:"message"` AsymmetricPublicKey string `json:"asymmetric_public_key"` AsymmetricPrivateKey string `json:"asymmetric_private_key"` UserID string `json:"user_id"` Username string `json:"username"` MessageExpiryDefault string `json:"message_expiry_default"` } func makeLoginResponse(w http.ResponseWriter, code int, message, pubKey, privKey string, user Models.User) { var ( status = "error" messageExpiryRaw driver.Value messageExpiry string returnJSON []byte err error ) if code >= 200 && code <= 300 { status = "success" } messageExpiryRaw, _ = user.MessageExpiryDefault.Value() messageExpiry, _ = messageExpiryRaw.(string) returnJSON, err = json.MarshalIndent(loginResponse{ Status: status, Message: message, AsymmetricPublicKey: pubKey, AsymmetricPrivateKey: privKey, UserID: user.ID.String(), Username: user.Username, MessageExpiryDefault: messageExpiry, }, "", " ") if err != nil { http.Error(w, "Error", http.StatusInternalServerError) return } // Return updated json w.WriteHeader(code) w.Write(returnJSON) } // Login logs the user into the system func Login(w http.ResponseWriter, r *http.Request) { var ( creds credentials userData Models.User session Models.Session expiresAt time.Time err error ) err = json.NewDecoder(r.Body).Decode(&creds) if err != nil { makeLoginResponse(w, http.StatusInternalServerError, "An error occurred", "", "", userData) return } userData, err = Database.GetUserByUsername(creds.Username) if err != nil { makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData) return } if !CheckPasswordHash(creds.Password, userData.Password) { makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData) return } // TODO: Revisit before production expiresAt = time.Now().Add(12 * time.Hour) session = Models.Session{ UserID: userData.ID, Expiry: expiresAt, } err = Database.CreateSession(&session) if err != nil { makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData) return } http.SetCookie(w, &http.Cookie{ Name: "session_token", Value: session.ID.String(), Expires: expiresAt, }) makeLoginResponse( w, http.StatusOK, "Successfully logged in", userData.AsymmetricPublicKey, userData.AsymmetricPrivateKey, userData, ) }