From eab81259e086a6b12f1e62828a31f8fb1bde97a4 Mon Sep 17 00:00:00 2001 From: Omri Bornstein Date: Wed, 7 Feb 2024 12:41:33 +1100 Subject: [PATCH] webauthn registering Signed-off-by: Omri Bornstein --- server/configuration/authentication.go | 92 ++++++++++++++++++++++++-- server/db/types.go | 14 ++-- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/server/configuration/authentication.go b/server/configuration/authentication.go index c24cef6..2a32439 100644 --- a/server/configuration/authentication.go +++ b/server/configuration/authentication.go @@ -2,6 +2,8 @@ package configuration import ( "context" + "encoding/json" + "fmt" "html/template" "net/http" "net/url" @@ -103,11 +105,93 @@ func (server *RakerServer) InstagramSignUp(writer http.ResponseWriter, request * } func (server *RakerServer) WebAuthnBeginRegistration(writer http.ResponseWriter, request *http.Request) { - // user := request.Context().Value(authenticatedUserKey).(db.User) - // options, session, err := server.WebAuthn.BeginRegistration(user) - // if err != nil { + user := request.Context().Value(authenticatedUserKey).(db.User) + options, session, err := server.WebAuthn.BeginRegistration(user) + if err != nil { + http.Error(writer, "incorrect credentials", http.StatusUnauthorized) + log.Error(err) + return + } + + user.Sessions = append(user.Sessions, *session) + + filter := bson.M{ + "_id": user.ID, + "username": user.Username, + } + update := bson.M{ + "$set": bson.M{ + "sessions": user.Sessions, + }, + } + + result, err := server.Users.UpdateOne(context.Background(), filter, update) + if err != nil { + http.Error(writer, "incorrect credentials", http.StatusInternalServerError) + log.Error(err, "ID", user.ID.Hex()) + return + } else if result.MatchedCount == 0 { + http.Error(writer, "incorrect credentials", http.StatusNotFound) + log.Error("the user was not found/modified", "ID", user.ID.Hex()) + } + + writer.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(writer).Encode(options); err != nil { + http.Error(writer, "incorrect credentials", http.StatusNotFound) + log.Error(err, "ID", user.ID.Hex()) + return + } + writer.WriteHeader(http.StatusOK) +} + +func (server *RakerServer) WebAuthnFinishRegistration(writer http.ResponseWriter, request *http.Request) { + user := request.Context().Value(authenticatedUserKey).(db.User) + if len(user.Sessions) == 0 { + http.Error(writer, "incorrect credentials", http.StatusUnauthorized) + log.Error(user.ID.Hex(), "doesn't have a valid FIDO session") + return + } + + session := user.Sessions[len(user.Sessions)-1] + credential, err := server.WebAuthn.FinishRegistration(user, session, request) + if err != nil { + // Handle Error and return. + http.Error(writer, "incorrect credentials", http.StatusUnauthorized) + log.Error(err, "ID", user.ID.Hex()) + return + } + + user.Credentials = append(user.Credentials, *credential) + + filter := bson.M{ + "_id": user.ID, + "username": user.Username, + } + update := bson.M{ + "$set": bson.M{ + "credentials": user.Credentials, + }, + "$pull": bson.M{ + "sessions": session, + }, + } + + result, err := server.Users.UpdateOne(context.Background(), filter, update) + if err != nil { + http.Error(writer, "incorrect credentials", http.StatusInternalServerError) + log.Error(err, "ID", user.ID.Hex()) + return + } else if result.MatchedCount == 0 { + http.Error(writer, "incorrect credentials", http.StatusNotFound) + log.Error("the user was not found/modified", "ID", user.ID.Hex()) + } + + fmt.Fprint(writer, "Registration Success") + writer.WriteHeader(http.StatusOK) +} + +func (server *RakerServer) WebAuthnBeginSignIn(writer http.ResponseWriter, request *http.Request) { - // } } func (server *RakerServer) InstagramSignIn(writer http.ResponseWriter, request *http.Request) { diff --git a/server/db/types.go b/server/db/types.go index f7dc9b2..1243a0c 100644 --- a/server/db/types.go +++ b/server/db/types.go @@ -40,10 +40,12 @@ var ( ) type User struct { - ID primitive.ObjectID `bson:"_id" json:"-"` - Username string `bson:"username" json:"-"` - Hash string `bson:"hash" json:"-"` - Instagram struct { + ID primitive.ObjectID `bson:"_id" json:"-"` + Username string `bson:"username" json:"-"` + Hash string `bson:"hash" json:"-"` + Credentials []webauthn.Credential `bson:"credentials" json:"-"` + Sessions []webauthn.SessionData `bson:"sessions" json:"-"` + Instagram struct { FBSR string `bson:"fbsr" json:"-"` SessionID string `bson:"session_id" json:"-"` UserID string `bson:"user_id" json:"-"` @@ -121,9 +123,7 @@ func (user User) WebAuthnDisplayName() string { } func (user User) WebAuthnCredentials() []webauthn.Credential { - return []webauthn.Credential{ - webauthn.Credential{}, - } + return user.Credentials } func (user User) WebAuthnIcon() string {