diff --git a/bot/google/token.go b/bot/google/token.go new file mode 100644 index 0000000..d73f941 --- /dev/null +++ b/bot/google/token.go @@ -0,0 +1,65 @@ +package google + +import ( + "bytes" + "encoding/json" + "io" + "net/http" +) + +type TokenRequestBody struct { + ClientId string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RedirectUri string `json:"redirect_uri"` + GrantType string `json:"grant_type"` + Code string `json:"code"` +} + +type TokenResponseBody struct { + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` + RefreshToken string `json:"refresh_token"` + Scope string `json:"scope"` + TokenType string `json:"token_type"` +} + +func (c *OAuthClient) GetToken(code string) (string, error) { + + reqBody := TokenRequestBody{ + ClientId: c.Config.ClientId, + ClientSecret: c.Config.ClientSecret, + RedirectUri: c.Config.RedirectUri, + GrantType: "authorization_code", + Code: code, + } + reqJson, err := json.Marshal(reqBody) + if err != nil { + return "", err + } + + req, err := http.NewRequestWithContext(c.ctx, http.MethodPost, c.Config.Endpoint+"/token", bytes.NewBuffer(reqJson)) + if err != nil { + return "", err + } + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + + var respBody TokenResponseBody + err = json.Unmarshal(body, &respBody) + if err != nil { + return "", err + } + + return respBody.RefreshToken, nil +} diff --git a/bot/handler/token.go b/bot/handler/token.go index 9b9e4e7..eb3d9f6 100644 --- a/bot/handler/token.go +++ b/bot/handler/token.go @@ -7,26 +7,29 @@ import ( "net/http" "github.com/claustra01/calendeye/db" + "github.com/claustra01/calendeye/google" ) -type TokenResponseBody struct { - RefreshToken string `json:"refresh_token"` +type TokenRequestBody struct { + Id string `json:"id"` + AuthCode string `json:"code"` } func UpdateRefreshToken(w http.ResponseWriter, req *http.Request) { defer func() { _ = req.Body.Close() }() - id := req.URL.Query().Get("id") - if id == "" { - w.WriteHeader(http.StatusBadRequest) - _, err := w.Write([]byte("id is required")) + body, err := io.ReadAll(req.Body) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + _, err := w.Write([]byte(err.Error())) if err != nil { log.Println(err) } return } - body, err := io.ReadAll(req.Body) + var reqBody TokenRequestBody + err = json.Unmarshal(body, &reqBody) if err != nil { w.WriteHeader(http.StatusInternalServerError) _, err := w.Write([]byte(err.Error())) @@ -36,8 +39,10 @@ func UpdateRefreshToken(w http.ResponseWriter, req *http.Request) { return } - var token TokenResponseBody - err = json.Unmarshal(body, &token) + client := google.NewOAuthClient( + req.Context(), + ) + token, err := client.GetToken(reqBody.AuthCode) if err != nil { w.WriteHeader(http.StatusInternalServerError) _, err := w.Write([]byte(err.Error())) @@ -46,8 +51,16 @@ func UpdateRefreshToken(w http.ResponseWriter, req *http.Request) { } return } + if token == "" { + w.WriteHeader(http.StatusBadRequest) + _, err := w.Write([]byte("Failed to get token")) + if err != nil { + log.Println(err) + } + return + } - err = db.UpdateRefreshToken(id, token.RefreshToken) + err = db.UpdateRefreshToken(reqBody.Id, token) if err == db.ErrNoRecord { w.WriteHeader(http.StatusNotFound) _, err := w.Write([]byte(err.Error()))