From faf42566f5d7b54caec62795995702dd1135a816 Mon Sep 17 00:00:00 2001 From: Maciej Bowszys Date: Sat, 4 Jul 2026 22:05:30 +0200 Subject: [PATCH] 260704_220530 --- README.md | 2 + go.mod | 1 + go.sum | 2 + moira_db.go | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 114 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ca7d61..6fe5bd2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # moira_db +To distribute the PWA, you may want to use https://www.pwabuilder.com/ + diff --git a/go.mod b/go.mod index be80428..c9d57ce 100644 --- a/go.mod +++ b/go.mod @@ -6,4 +6,5 @@ require ( github.com/tidwall/gjson v1.19.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect ) diff --git a/go.sum b/go.sum index c3915ad..6808ace 100644 --- a/go.sum +++ b/go.sum @@ -4,3 +4,5 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= diff --git a/moira_db.go b/moira_db.go index 4435a15..3dd6136 100644 --- a/moira_db.go +++ b/moira_db.go @@ -1,6 +1,8 @@ package main import ( + "encoding/json" + "errors" "fmt" "html/template" "io" @@ -10,10 +12,14 @@ import ( "os" "strings" "time" - "encoding/json" - "errors" + "crypto/rand" + "encoding/base64" "github.com/tidwall/gjson" + + "context" // <- TODO: what's this?? + + "golang.org/x/oauth2" //"path/filepath" //"regexp" //"strings" @@ -25,6 +31,101 @@ import ( var templates *template.Template = template.New("") var client = &http.Client{Timeout: 2*time.Second} +var oauth2_dc_config = &oauth2.Config{ + ClientID: os.Getenv("MOIRA_OAUTH2_DC_CLI_ID"), + ClientSecret: os.Getenv("MOIRA_OAUTH2_DC_CLI_SECRET"), + Scopes: []string{"identify", "email"}, + RedirectURL: "https://moira.makemore.cloud/oauth2/ext/dc/clbk/", + Endpoint: oauth2.Endpoint{ + AuthURL: "https://discord.com/oauth2/authorize", + TokenURL: "https://discord.com/api/oauth2/token", + }, +} + +func oauth2_dc_genRandState() (_ string, err error){ + ret := make([]byte, 24) + + _, err = rand.Read(ret) + if err != nil{ return } + + return base64.RawURLEncoding.EncodeToString(ret), nil +} + +func oauth2_dc_genLoginURL() (_ string, _ *http.Cookie, err error){ + state, err := oauth2_dc_genRandState() + if err != nil{ return } + + ret_cookie := &http.Cookie{ + Name: "oauth_state", + Value: state, + Path: "/", + HttpOnly: true, + Secure: true, + SameSite: http.SameSiteLaxMode, // TODO: what's lax?? + MaxAge: 600, + } + + return oauth2_dc_config.AuthCodeURL(state), ret_cookie, nil +} + +func oauth2_dc_exchangeReceivedCode(req *http.Request) (_ *http.Client, err error){ + cookie, err := req.Cookie("oauth_state") + if err != nil{ return } + if cookie.Value != req.URL.Query().Get("state"){ + err = errors.New("oauth2_dc: csrf test failed") + return + } + + token, err := oauth2_dc_config.Exchange(context.Background(), req.URL.Query().Get("code")) + if err != nil{ return } + + return oauth2_dc_config.Client(context.Background(), token), nil +} + +func oauth2_fetch_dc_userInfo(in_client *http.Client) (ret string, err error){ + req, err := http.NewRequest("GET", "https://discord.com/api/users/@me", nil) + if err != nil{ return } + + //req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; MoiraBot/1.0)") + + resp,err := in_client.Do(req) + if err != nil{ return } + defer resp.Body.Close() + + resp_text, err := io.ReadAll(resp.Body) + if err != nil{ return } + //fmt.Printf("%+v\n", string(resp_text)) + + return string(resp_text), nil +} + +func oauth2_dc_userInfo_to_User(resp_text string) (err error){ // TODO: add User{} return + fmt.Printf("%s\n", resp_text) + + return nil +} + +func oauth2_hdlr_login(resp http.ResponseWriter, req *http.Request){ + url, cookie, err := oauth2_dc_genLoginURL() + if err != nil { + http.Error(resp, err.Error(), http.StatusInternalServerError) + } + + http.SetCookie(resp, cookie) + http.Redirect(resp, req, url, http.StatusFound) +} + +func oauth2_hdlr_clbk(resp http.ResponseWriter, req *http.Request){ + client, err := oauth2_dc_exchangeReceivedCode(req) + if err != nil { return } // TODO: should the error be reported somehow? + + resp_text, err := oauth2_fetch_dc_userInfo(client) + if err != nil { return } // TODO: should the error be reported somehow? + + err = oauth2_dc_userInfo_to_User(resp_text) + if err != nil { return } // TODO: should the error be reported somehow? +} + type Film struct{ Title_orig, @@ -260,6 +361,9 @@ func hdlr_film_parseMsg(resp http.ResponseWriter, req *http.Request){ } func main(){ + fmt.Println("CLIENT_ID:", oauth2_dc_config.ClientID); + fmt.Println("CLIENT_SECRET:", oauth2_dc_config.ClientSecret); + //t_film, _ := fetch_filmInfo("https://www.filmweb.pl/film/Spirited+Away%3A+W+krainie+Bog%C3%B3w-2001-33288") //t_film, _ := fetch_filmInfo("https://www.filmweb.pl/film/Pulp+Fiction-1994-1039") //t_film, _ := fetch_filmInfo("https://www.filmweb.pl/film/Kl%C4%85twa+Doliny+W%C4%99%C5%BCy-1987-6785") @@ -298,8 +402,10 @@ func main(){ http.HandleFunc("/film/parse_msg/", hdlr_film_parseMsg) + http.HandleFunc("/oauth2/ext/dc/login/", oauth2_hdlr_login) + http.HandleFunc("/oauth2/ext/dc/clbk/", oauth2_hdlr_clbk) //fmt.Println("Welcome to moira_db!"); - log.Fatal(http.ListenAndServe("127.0.0.1:8099", nil)) + log.Fatal(http.ListenAndServe(":8099", nil)) }