camper/pkg/user/login_attempt.go

82 lines
2.1 KiB
Go

package user
import (
"context"
httplib "dev.tandem.ws/tandem/camper/pkg/http"
"fmt"
"net/http"
"time"
"dev.tandem.ws/tandem/camper/pkg/auth"
"dev.tandem.ws/tandem/camper/pkg/database"
"dev.tandem.ws/tandem/camper/pkg/template"
)
func serveLoginAttemptIndex(w http.ResponseWriter, r *http.Request, loginAttempt *auth.User, company *auth.Company, conn *database.Conn) {
filters := newFilterForm()
if err := filters.Parse(r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
loginAttempts, err := collectLoginAttemptEntries(r.Context(), conn, filters)
if err != nil {
panic(err)
}
index := &loginAttemptIndex{
Attempts: filters.buildCursor(loginAttempts),
Filters: filters,
}
index.MustRender(w, r, loginAttempt, company)
}
func collectLoginAttemptEntries(ctx context.Context, conn *database.Conn, filters *filterForm) ([]*loginAttemptEntry, error) {
where, args := filters.BuildQuery(nil)
rows, err := conn.Query(ctx, fmt.Sprintf(`
select attempt_id
, user_name
, host(ip_address)
, attempted_at
, success
from company_login_attempt
where (%s)
order by attempted_at desc, attempt_id desc
limit %d
`, where, filters.PerPage()+1), args...)
if err != nil {
return nil, err
}
defer rows.Close()
var entries []*loginAttemptEntry
for rows.Next() {
entry := &loginAttemptEntry{}
if err = rows.Scan(&entry.ID, &entry.UserName, &entry.IPAddress, &entry.Date, &entry.Success); err != nil {
return nil, err
}
entries = append(entries, entry)
}
return entries, nil
}
type loginAttemptEntry struct {
ID int
UserName string
IPAddress string
Date time.Time
Success bool
}
type loginAttemptIndex struct {
Attempts []*loginAttemptEntry
Filters *filterForm
}
func (page *loginAttemptIndex) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
if httplib.IsHTMxRequest(r) && page.Filters.Paginated() {
template.MustRenderAdminNoLayout(w, r, user, company, "user/results.gohtml", page)
} else {
template.MustRenderAdminFiles(w, r, user, company, page, "user/login-attempts.gohtml", "user/results.gohtml")
}
}