package app import ( "farga/db/types" "farga/lib" o "farga/lib/oauth2" "fmt" "net/http" "time" "golang.org/x/oauth2" ) // sends user to hackatime oauth2 func (a *App) HackatimeLogin(w http.ResponseWriter, r *http.Request) { user := r.Context().Value(lib.UserKey).(*types.User) state, err := a.Store.CreateOAuthState(user.ID) if err != nil { http.Error(w, "500 Internal Server Error", http.StatusInternalServerError) return } oAuthConf := o.HackatimeConfig() url := oAuthConf.AuthCodeURL(state.State, oauth2.S256ChallengeOption(state.Verifier)) http.Redirect(w, r, url, http.StatusFound) } func (a *App) HackatimeCallback(w http.ResponseWriter, r *http.Request) { stateID := r.URL.Query().Get("state") state, err := a.Store.OAuthState(stateID) if err != nil { http.Error(w, "Invalid state.", http.StatusBadRequest) return } a.Store.RemoveOAuthState(state.ID) if time.Now().After(state.ExpiresAt) { http.Error(w, "State expired", http.StatusBadRequest) return } code := r.URL.Query().Get("code") oAuthConf := o.HackatimeConfig() token, err := oAuthConf.Exchange(r.Context(), code, oauth2.VerifierOption(state.Verifier)) if err != nil { http.Error(w, err.Error(), 500) return } err = a.Store.SaveHackatimeToken(*state.UserID, token.AccessToken) if err != nil { fmt.Println("BAD ERROR: ", err) http.Error(w, "Something went wrong on our end.", http.StatusInternalServerError) return } http.Redirect(w, r, "/config?msg=HackatimeLinked", http.StatusSeeOther) }