authentricity/internal/webui/act_webauthn.go

105 lines
2.2 KiB
Go

package webui
import (
"fmt"
"net/http"
"time"
"go.e43.eu/authentricity/internal/models"
"go.e43.eu/authentricity/internal/store"
"go.uber.org/zap"
)
func (s *Service) actionAddAuthenticator(
w http.ResponseWriter,
r *http.Request,
ent models.Entity,
md store.EntryMetadata,
) {
user, ok := ent.(*models.UserRecord)
if !ok {
s.renderBadRequest(w, r)
return
}
tok := getUserToken(r.Context())
isYou := user.UUID.String() == tok.Subject()
if !isYou {
s.renderForbidden(w, r)
return
}
rr := WebAuthnRegistrationResponse{
Session: r.PostForm.Get("session"),
Response: r.PostForm.Get("response"),
}
cred, err := s.webAuthnCreateCredential(user, rr)
if err != nil {
zap.L().Error("Error creating credential", zap.Reflect("error", err))
s.renderError(w)
}
pkCred := models.PublicKeyCredential{
Credential: cred.ID,
PublicKey: cred.PublicKey,
UserPresent: cred.Flags.UserPresent,
UserVerified: cred.Flags.UserVerified,
Comment: fmt.Sprintf("Added %s", time.Now().Format("Mon Jan _2 2006")),
}
priv := user.EnsurePrivileged()
priv.PublicKeyCredentials = append(priv.PublicKeyCredentials, pkCred)
if err := s.store.UpdateEntitySimple(r.Context(), user, md); err != nil {
zap.L().Error("Error updating user", zap.Error(err))
s.renderError(w)
} else {
s.renderEntity(w, r, ent, "Authenticator Added")
}
}
func (s *Service) actionRemoveCredentials(
w http.ResponseWriter,
r *http.Request,
ent models.Entity,
md store.EntryMetadata,
) {
user, ok := ent.(*models.UserRecord)
if !ok {
s.renderBadRequest(w, r)
return
}
if !s.canEditEntity(r.Context(), user.UUID) {
s.renderForbidden(w, r)
return
}
toRemove := r.PostForm["credential"]
priv := user.EnsurePrivileged()
var newCreds []models.PublicKeyCredential
for _, cred := range priv.PublicKeyCredentials {
remove := false
for _, kr := range toRemove {
if cred.Credential.String() == kr {
remove = true
}
}
if !remove {
newCreds = append(newCreds, cred)
}
}
priv.PublicKeyCredentials = newCreds
if err := s.store.UpdateEntitySimple(r.Context(), user, md); err != nil {
zap.L().Error("Error updating user", zap.Error(err))
s.renderError(w)
} else {
s.renderEntity(w, r, ent, "Credentials removed")
}
}