From 9a1b6de7f4c4659effd7a8a4042fa0ede5a2d8e2 Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 7 Jun 2024 14:40:12 +0100 Subject: [PATCH] Working --- .docker/Dockerfile | 5 +-- auth/auth.go | 102 +++++++++++++++++++++++++++------------------ game/handler.go | 19 +++++++-- 3 files changed, 78 insertions(+), 48 deletions(-) diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 2d20f95..5846ae9 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -15,9 +15,6 @@ RUN /usr/local/gcloud/google-cloud-sdk/bin/gcloud components install app-engine- # Add the gcloud command-line tool to your path. ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin -# # Run dev_appserver.py . from inside the repo -# RUN dev_appserver.py . - # Set the working directory in the container WORKDIR /go/src/app @@ -30,6 +27,8 @@ EXPOSE 8080 # Expose port 80 for http traffic EXPOSE 80 +RUN chmod +x set-discord-bot-credentials.sh + # Expose port 8000 to the outside world EXPOSE 8000 diff --git a/auth/auth.go b/auth/auth.go index a612633..eb067f9 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -53,12 +53,13 @@ const ( ) const ( - UserKind = "User" - naClKind = "NaCl" - oAuthKind = "OAuth" - redirectURLKind = "RedirectURL" - superusersKind = "Superusers" - prodKey = "prod" + UserKind = "User" + naClKind = "NaCl" + oAuthKind = "OAuth" + redirectURLKind = "RedirectURL" + superusersKind = "Superusers" + discordBotCredentialsKind = "DiscordBotCredentials" + prodKey = "prod" ) const ( @@ -66,17 +67,58 @@ const ( ) var ( - prodOAuth *OAuth - prodOAuthLock = sync.RWMutex{} - prodNaCl *naCl - prodNaClLock = sync.RWMutex{} - prodSuperusers *Superusers - prodSuperusersLock = sync.RWMutex{} - router *mux.Router + prodOAuth *OAuth + prodOAuthLock = sync.RWMutex{} + prodNaCl *naCl + prodNaClLock = sync.RWMutex{} + prodSuperusers *Superusers + prodSuperusersLock = sync.RWMutex{} + prodDiscordBotCredentials *DiscordBotCredentials + prodDiscordBotCredentialsLock = sync.RWMutex{} + router *mux.Router RedirectURLResource *Resource ) +type DiscordBotCredentials struct { + Username string + Password string +} + +func getDiscordBotCredentialsKey(ctx context.Context) *datastore.Key { + return datastore.NewKey(ctx, discordBotCredentialsKind, prodKey, 0, nil) +} + +func SetDiscordBotCredentials(ctx context.Context, discordBotCredentials *DiscordBotCredentials) error { + return datastore.RunInTransaction(ctx, func(ctx context.Context) error { + currentDiscordBotCredentials := &DiscordBotCredentials{} + if err := datastore.Get(ctx, getDiscordBotCredentialsKey(ctx), currentDiscordBotCredentials); err == nil { + return HTTPErr{"DiscordBotCredentials already configured", http.StatusBadRequest} + } + if _, err := datastore.Put(ctx, getDiscordBotCredentialsKey(ctx), discordBotCredentials); err != nil { + return err + } + return nil + }, &datastore.TransactionOptions{XG: false}) +} + +func getDiscordBotCredentials(ctx context.Context) (*DiscordBotCredentials, error) { + prodDiscordBotCredentialsLock.RLock() + if prodDiscordBotCredentials != nil { + defer prodDiscordBotCredentialsLock.RUnlock() + return prodDiscordBotCredentials, nil + } + prodDiscordBotCredentialsLock.RUnlock() + prodDiscordBotCredentialsLock.Lock() + defer prodDiscordBotCredentialsLock.Unlock() + foundDiscordBotCredentials := &DiscordBotCredentials{} + if err := datastore.Get(ctx, getDiscordBotCredentialsKey(ctx), foundDiscordBotCredentials); err != nil { + return nil, err + } + prodDiscordBotCredentials = foundDiscordBotCredentials + return prodDiscordBotCredentials, nil +} + func init() { RedirectURLResource = &Resource{ Delete: deleteRedirectURL, @@ -532,63 +574,41 @@ func handleLogin(w ResponseWriter, r Request) error { return nil } -var USERNAME = "username" -var PASSWORD = "password" - func handleDiscordBotLogin(w ResponseWriter, r Request) error { ctx := appengine.NewContext(r.Req()) + discordBotCredentials, err := getDiscordBotCredentials(ctx) + if err != nil { + return HTTPErr{"Unable to load discord bot credentials", http.StatusInternalServerError} + } + authHeader := r.Req().Header.Get("Authorization") if !strings.HasPrefix(authHeader, "Basic ") { - // return HTTPErr{ - // Body: "Authorization header must be Basic", - // Status: http.StatusBadRequest, - // } return HTTPErr{"Authorization header must be Basic", http.StatusBadRequest} } decoded, err := base64.StdEncoding.DecodeString(authHeader[6:]) if err != nil { - // return HTTPErr{ - // Body: "Unable to decode authorization header", - // Status: http.StatusBadRequest, - // } return HTTPErr{"Unable to decode authorization header", http.StatusBadRequest} } parts := strings.Split(string(decoded), ":") if len(parts) != 2 { - // return HTTPErr{ - // Body: "Authorization header format not username:password", - // Status: http.StatusBadRequest, - // } return HTTPErr{"Authorization header format not username:password", http.StatusBadRequest} } - if parts[0] != USERNAME || parts[1] != PASSWORD { - // return HTTPErr{ - // Body: "Unauthorized", - // Status: http.StatusUnauthorized, - // } + if parts[0] != discordBotCredentials.Username || parts[1] != discordBotCredentials.Password { return HTTPErr{"Unauthorized", http.StatusUnauthorized} } discordBotUser := createDiscordBotUser() if _, err := datastore.Put(ctx, UserID(ctx, discordBotUser.Id), discordBotUser); err != nil { - // return HTTPErr{ - // Body: "Unable to store user", - // Status: http.StatusInternalServerError, - // } return HTTPErr{"Unable to store user", http.StatusInternalServerError} } token, err := encodeUserToToken(ctx, discordBotUser) if err != nil { - // return HTTPErr{ - // Body: "Unable to encode user to token", - // Status: http.StatusInternalServerError, - // } return HTTPErr{"Unable to encode user to token", http.StatusInternalServerError} } diff --git a/game/handler.go b/game/handler.go index 888289b..8440107 100644 --- a/game/handler.go +++ b/game/handler.go @@ -655,16 +655,20 @@ func createAllocation(w ResponseWriter, r Request) (*Allocation, error) { } type configuration struct { - OAuth *auth.OAuth - FCMConf *FCMConf - SendGrid *auth.SendGrid - Superusers *auth.Superusers + OAuth *auth.OAuth + FCMConf *FCMConf + SendGrid *auth.SendGrid + Superusers *auth.Superusers + DiscordBotCredentials *auth.DiscordBotCredentials } func handleConfigure(w ResponseWriter, r Request) error { ctx := appengine.NewContext(r.Req()) + log.Infof(ctx, "handleConfigure called") + fmt.Printf("handleConfigure called") conf := &configuration{} + log.Infof(ctx, "handleConfigure called with %+v", conf) if err := json.NewDecoder(r.Req().Body).Decode(conf); err != nil { return err } @@ -688,6 +692,13 @@ func handleConfigure(w ResponseWriter, r Request) error { return err } } + fmt.Printf("DiscordBotCredentials: %+v", conf.DiscordBotCredentials) + log.Infof(ctx, "DiscordBotCredentials: %+v", conf.DiscordBotCredentials) + if conf.DiscordBotCredentials != nil { + if err := auth.SetDiscordBotCredentials(ctx, conf.DiscordBotCredentials); err != nil { + return err + } + } return nil }