summaryrefslogtreecommitdiff
path: root/server/guest/handler.go
diff options
context:
space:
mode:
authorMichael Hunteman <michael@huntm.net>2024-08-25 12:44:32 -0700
committerMichael Hunteman <michael@huntm.net>2024-08-25 12:44:32 -0700
commit096a08708e2310becba56a237ef63b5cf6e3c4c4 (patch)
tree2924f9aecdcf035599558552cfdb20c2cc18f7d1 /server/guest/handler.go
parent6aee47e76d7e25206b3778aeebcc341d7b705035 (diff)
Add admin dashboard
Diffstat (limited to 'server/guest/handler.go')
-rw-r--r--server/guest/handler.go115
1 files changed, 63 insertions, 52 deletions
diff --git a/server/guest/handler.go b/server/guest/handler.go
index 46b8a45..153a633 100644
--- a/server/guest/handler.go
+++ b/server/guest/handler.go
@@ -12,15 +12,15 @@ import (
)
var (
- guestRe = regexp.MustCompile(`^/guest/*$`)
- guestIdRe = regexp.MustCompile(`^/guest/([0-9]+)$`)
+ guestRegex = regexp.MustCompile(`^/guest/*$`)
+ guestIDRegex = regexp.MustCompile(`^/guest/([0-9]+)$`)
)
type GuestHandler struct {
- store guestStore
+ guestStore GuestStore
}
-type guestStore interface {
+type GuestStore interface {
Find(credentials Credentials) (Guest, error)
Get() ([]Guest, error)
Add(guest Guest) error
@@ -33,9 +33,9 @@ type appError struct {
Code int
}
-func NewGuestHandler(s guestStore) *GuestHandler {
+func NewGuestHandler(guestStore GuestStore) *GuestHandler {
return &GuestHandler{
- store: s,
+ guestStore,
}
}
@@ -45,11 +45,11 @@ func (guestHandler *GuestHandler) ServeHTTP(responseWriter http.ResponseWriter,
responseWriter.WriteHeader(http.StatusOK)
case request.Method == http.MethodPost && request.URL.Path == "/guest/login":
guestHandler.handleLogIn(responseWriter, request)
- case request.Method == http.MethodPut && guestIdRe.MatchString(request.URL.Path):
+ case request.Method == http.MethodPut && guestIDRegex.MatchString(request.URL.Path):
guestHandler.handlePut(responseWriter, request)
- case request.Method == http.MethodGet && guestRe.MatchString(request.URL.Path):
+ case request.Method == http.MethodGet && guestRegex.MatchString(request.URL.Path):
guestHandler.handleGet(responseWriter, request)
- case request.Method == http.MethodPost && guestRe.MatchString(request.URL.Path):
+ case request.Method == http.MethodPost && guestIDRegex.MatchString(request.URL.Path):
guestHandler.handlePost(responseWriter, request)
default:
responseWriter.WriteHeader(http.StatusNotFound)
@@ -57,7 +57,7 @@ func (guestHandler *GuestHandler) ServeHTTP(responseWriter http.ResponseWriter,
}
func (guestHandler *GuestHandler) handleLogIn(responseWriter http.ResponseWriter, request *http.Request) {
- token, err := guestHandler.logInGuest(request)
+ token, err := guestHandler.logIn(request)
if err != nil {
http.Error(responseWriter, err.Message, err.Code)
} else {
@@ -90,28 +90,28 @@ func (guestHandler *GuestHandler) handlePost(responseWriter http.ResponseWriter,
}
}
-func (guestHandler *GuestHandler) logInGuest(request *http.Request) ([]byte, *appError) {
+func (guestHandler *GuestHandler) logIn(request *http.Request) ([]byte, *appError) {
credentials, err := guestHandler.decodeCredentials(request)
if err != nil {
- return []byte{}, &appError{err, "Failed to unmarshal credentials", http.StatusBadRequest}
+ return []byte{}, &appError{err, "failed to unmarshal credentials", http.StatusBadRequest}
}
- guest, err := guestHandler.store.Find(credentials)
+ guest, err := guestHandler.guestStore.Find(credentials)
if err != nil {
- return []byte{}, &appError{err, "Guest not found", http.StatusUnauthorized}
+ return []byte{}, &appError{err, "guest not found", http.StatusUnauthorized}
}
expirationTime := guestHandler.setExpirationTime()
claims := guestHandler.createClaims(credentials, expirationTime)
- key, err := guestHandler.readKey()
+ key, err := guestHandler.readGuestKey()
if err != nil {
- return []byte{}, &appError{err, "Failed to read secret key", http.StatusInternalServerError}
+ return []byte{}, &appError{err, "failed to read secret key", http.StatusInternalServerError}
}
token, err := guestHandler.createToken(claims, key)
if err != nil {
- return []byte{}, &appError{err, "Failed to create token", http.StatusInternalServerError}
+ return []byte{}, &appError{err, "failed to create token", http.StatusInternalServerError}
}
jsonBytes, err := guestHandler.marshalResponse(guest, token)
if err != nil {
- return []byte{}, &appError{err, "Failed to marshal response", http.StatusInternalServerError}
+ return []byte{}, &appError{err, "failed to marshal response", http.StatusInternalServerError}
}
return jsonBytes, nil
}
@@ -136,9 +136,13 @@ func (guestHandler *GuestHandler) createClaims(credentials Credentials, expirati
}
}
-func (guestHandler *GuestHandler) readKey() ([]byte, error) {
+func (guestHandler *GuestHandler) readGuestKey() ([]byte, error) {
// TODO: use properties file
- return os.ReadFile("C:\\Users\\mhunt\\skey.pem")
+ return os.ReadFile("C:\\Users\\mhunt\\guest.pem")
+}
+
+func (guestHandler *GuestHandler) readAdminKey() ([]byte, error) {
+ return os.ReadFile("C:\\Users\\mhunt\\admin.pem")
}
func (guestHandler *GuestHandler) createToken(claims *Claims, key []byte) (string, error) {
@@ -159,38 +163,38 @@ func (guestHandler *GuestHandler) createLoginResponse(weddingGuest Guest, token
}
func (guestHandler *GuestHandler) putGuest(request *http.Request) *appError {
- if err := guestHandler.validateToken(request); err != nil {
+ guestKey, err := guestHandler.readGuestKey()
+ if err != nil {
+ return &appError{err, "failed to read secret key", http.StatusInternalServerError}
+ }
+ if err := guestHandler.validateToken(request, guestKey); err != nil {
return err
}
- if guestHandler.findId(request) {
- return &appError{errors.New("ID not found"), "ID not found", http.StatusNotFound}
+ if guestHandler.findID(request) {
+ return &appError{errors.New("id not found"), "id not found", http.StatusNotFound}
}
guest, err := guestHandler.decodeGuest(request)
if err != nil {
- return &appError{err, "Invalid guest", http.StatusBadRequest}
+ return &appError{err, "invalid guest", http.StatusBadRequest}
}
- if err := guestHandler.store.Update(guest); err != nil {
- return &appError{err, "Failed to update guest", http.StatusInternalServerError}
+ if err := guestHandler.guestStore.Update(guest); err != nil {
+ return &appError{err, "failed to update guest", http.StatusInternalServerError}
}
return nil
}
-func (guestHandler *GuestHandler) validateToken(request *http.Request) *appError {
+func (guestHandler *GuestHandler) validateToken(request *http.Request, key []byte) *appError {
authorizationHeader := guestHandler.getToken(request)
- claims := guestHandler.initializeClaims()
- key, err := guestHandler.readKey()
- if err != nil {
- return &appError{err, "Failed to read secret key", http.StatusInternalServerError}
- }
+ claims := guestHandler.newClaims()
token, err := guestHandler.parseWithClaims(authorizationHeader, claims, key)
if err != nil {
if err == jwt.ErrSignatureInvalid {
- return &appError{err, "Invalid signature", http.StatusUnauthorized}
+ return &appError{err, "invalid signature", http.StatusUnauthorized}
}
- return &appError{err, "Failed to parse claims", http.StatusBadRequest}
+ return &appError{err, "failed to parse claims", http.StatusBadRequest}
}
if !token.Valid {
- return &appError{err, "Invalid token", http.StatusUnauthorized}
+ return &appError{err, "invalid token", http.StatusUnauthorized}
}
return nil
}
@@ -199,7 +203,7 @@ func (guestHandler *GuestHandler) getToken(request *http.Request) string {
return request.Header.Get("Authorization")
}
-func (guestHandler *GuestHandler) initializeClaims() *Claims {
+func (guestHandler *GuestHandler) newClaims() *Claims {
return &Claims{}
}
@@ -209,8 +213,8 @@ func (guestHandler *GuestHandler) parseWithClaims(token string, claims *Claims,
})
}
-func (guestHandler *GuestHandler) findId(request *http.Request) bool {
- matches := guestIdRe.FindStringSubmatch(request.URL.Path)
+func (guestHandler *GuestHandler) findID(request *http.Request) bool {
+ matches := guestIDRegex.FindStringSubmatch(request.URL.Path)
return len(matches) < 2
}
@@ -222,46 +226,53 @@ func (guestHandler *GuestHandler) decodeGuest(request *http.Request) (Guest, err
}
func (guestHandler *GuestHandler) getGuests(request *http.Request) ([]byte, *appError) {
- // TODO: check with admin token
- if err := guestHandler.validateToken(request); err != nil {
+ adminKey, err := guestHandler.readAdminKey()
+ if err != nil {
+ return []byte{}, &appError{err, "failed to read secret key", http.StatusInternalServerError}
+ }
+ if err := guestHandler.validateToken(request, adminKey); err != nil {
return []byte{}, err
}
- guests, err := guestHandler.store.Get()
+ guests, err := guestHandler.guestStore.Get()
if err != nil {
- return []byte{}, &appError{err, "Failed to get guests", http.StatusInternalServerError}
+ return []byte{}, &appError{err, "failed to get guests", http.StatusInternalServerError}
}
jsonBytes, err := json.Marshal(guests)
if err != nil {
- return []byte{}, &appError{err, "Failed to marshal guests", http.StatusInternalServerError}
+ return []byte{}, &appError{err, "failed to marshal guests", http.StatusInternalServerError}
}
return jsonBytes, nil
}
func (guestHandler *GuestHandler) postGuest(request *http.Request) *appError {
- if err := guestHandler.validateToken(request); err != nil {
+ adminKey, err := guestHandler.readAdminKey()
+ if err != nil {
+ return &appError{err, "failed to read secret key", http.StatusInternalServerError}
+ }
+ if err := guestHandler.validateToken(request, adminKey); err != nil {
return err
}
guest, err := guestHandler.decodeGuest(request)
if err != nil {
- return &appError{err, "Invalid guest", http.StatusBadRequest}
+ return &appError{err, "invalid guest", http.StatusBadRequest}
}
- guests, err := guestHandler.store.Get()
+ guests, err := guestHandler.guestStore.Get()
if err != nil {
- return &appError{err, "Failed to get guests", http.StatusInternalServerError}
+ return &appError{err, "failed to get guests", http.StatusInternalServerError}
}
if err := guestHandler.checkExistingGuests(guests, guest); err != nil {
- return &appError{err, "ID already exists", http.StatusConflict}
+ return &appError{err, "id already exists", http.StatusConflict}
}
- if err := guestHandler.store.Add(guest); err != nil {
- return &appError{err, "Failed to add guest", http.StatusInternalServerError}
+ if err := guestHandler.guestStore.Add(guest); err != nil {
+ return &appError{err, "failed to add guest", http.StatusInternalServerError}
}
return nil
}
func (guestHandler *GuestHandler) checkExistingGuests(guests []Guest, newGuest Guest) error {
for _, guest := range guests {
- if guest.Id == newGuest.Id {
- return errors.New("ID already exists")
+ if guest.ID == newGuest.ID {
+ return errors.New("id already exists")
}
}
return nil