last_activity user field

pull/3138/head
root 2024-04-15 11:27:43 +03:00
parent 8e79294413
commit ee47b3651a
6 changed files with 49 additions and 5 deletions

14
controllers/api/user.go Normal file → Executable file
View File

@ -5,6 +5,7 @@ import (
"errors"
"net/http"
"strconv"
"time"
"github.com/gophish/gophish/auth"
ctx "github.com/gophish/gophish/context"
@ -29,11 +30,12 @@ var ErrInsufficientPermission = errors.New("Permission denied")
// userRequest is the payload which represents the creation of a new user.
type userRequest struct {
Username string `json:"username"`
Password string `json:"password"`
Role string `json:"role"`
PasswordChangeRequired bool `json:"password_change_required"`
AccountLocked bool `json:"account_locked"`
Username string `json:"username"`
Password string `json:"password"`
Role string `json:"role"`
PasswordChangeRequired bool `json:"password_change_required"`
AccountLocked bool `json:"account_locked"`
LastActivity time.Time `json:"last_acitvity"`
}
func (ur *userRequest) Validate(existingUser *models.User) error {
@ -109,7 +111,9 @@ func (as *Server) Users(w http.ResponseWriter, r *http.Request) {
Role: role,
RoleID: role.ID,
PasswordChangeRequired: ur.PasswordChangeRequired,
LastActivity ur.LastActivity,
}
err = models.PutUser(&user)
if err != nil {
JSONResponse(w, models.Response{Success: false, Message: err.Error()}, http.StatusInternalServerError)

1
controllers/route.go Normal file → Executable file
View File

@ -123,6 +123,7 @@ func (as *AdminServer) Shutdown() error {
func (as *AdminServer) registerRoutes() {
router := mux.NewRouter()
// Base Front-end routes
router.Use(mid.UserActivityHandler)
router.HandleFunc("/", mid.Use(as.Base, mid.RequireLogin))
router.HandleFunc("/login", mid.Use(as.Login, as.limiter.Limit))
router.HandleFunc("/logout", mid.Use(as.Logout, mid.RequireLogin))

View File

@ -0,0 +1,9 @@
-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
ALTER TABLE `users`
ADD COLUMN `last_acitivty` DATETIME NULL;
-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

View File

@ -0,0 +1,9 @@
-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
ALTER TABLE `users`
ADD COLUMN `last_acitivty` DATETIME NULL;
-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back

20
middleware/middleware.go Normal file → Executable file
View File

@ -5,8 +5,10 @@ import (
"fmt"
"net/http"
"strings"
"time"
ctx "github.com/gophish/gophish/context"
log "github.com/gophish/gophish/logger"
"github.com/gophish/gophish/models"
"github.com/gorilla/csrf"
)
@ -39,6 +41,24 @@ func Use(handler http.HandlerFunc, mid ...func(http.Handler) http.HandlerFunc) h
return handler
}
func UserActivityHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Update the LastActivity timestamp for the logged-in user
if u := ctx.Get(r, "user"); u != nil {
currentUser := u.(models.User)
currentUser.LastActivity = time.Now()
if err := models.PutUser(&currentUser); err != nil {
// Handle error
log.Errorf("Failed to update user last activity: %v", err)
http.Error(w, "Failed to update user last activity", http.StatusInternalServerError)
return
}
}
// Call the next handler in the chain
next.ServeHTTP(w, r)
})
}
// GetContext wraps each request in a function which fills in the context for a given request.
// This includes setting the User and Session keys and values as necessary for use in later functions.
func GetContext(handler http.Handler) http.HandlerFunc {

1
models/user.go Normal file → Executable file
View File

@ -23,6 +23,7 @@ type User struct {
PasswordChangeRequired bool `json:"password_change_required"`
AccountLocked bool `json:"account_locked"`
LastLogin time.Time `json:"last_login"`
LastActivity time.Time `json:"last_activity"`
}
// GetUser returns the user that the given id corresponds to. If no user is found, an