From c222a814e4b787fd98b46b2be57ed973afa56c56 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Wed, 7 Jun 2017 21:12:59 +0200 Subject: [PATCH] Implemented Google login --- google.go | 47 ++++++++++++++++++++----- jobs/airing-anime/airing-anime.go | 6 +++- jobs/user-references/user-references.go | 4 ++- pages/dashboard/dashboard.go | 15 ++++++++ 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/google.go b/google.go index 1e8d2eb6..7885f58e 100644 --- a/google.go +++ b/google.go @@ -4,14 +4,27 @@ import ( "encoding/json" "errors" "io/ioutil" - "log" "net/http" "github.com/aerogo/aero" + "github.com/animenotifier/arn" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) +// GoogleUser is the user data we receive from Google +type GoogleUser struct { + Sub string `json:"sub"` + Name string `json:"name"` + GivenName string `json:"given_name"` + FamilyName string `json:"family_name"` + Profile string `json:"profile"` + Picture string `json:"picture"` + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + Gender string `json:"gender"` +} + // EnableGoogleLogin enables Google login for the app. func EnableGoogleLogin(app *aero.Application) { var api APIKeys @@ -30,7 +43,8 @@ func EnableGoogleLogin(app *aero.Application) { // Auth app.Get("/auth/google", func(ctx *aero.Context) string { - url := conf.AuthCodeURL(ctx.Session().ID()) + sessionID := ctx.Session().ID() + url := conf.AuthCodeURL(sessionID) ctx.Redirect(url) return "" }) @@ -38,11 +52,12 @@ func EnableGoogleLogin(app *aero.Application) { // Auth Callback app.Get("/auth/google/callback", func(ctx *aero.Context) string { if ctx.Session().ID() != ctx.Query("state") { - return ctx.Error(http.StatusBadRequest, "Authorization not allowed for this session", errors.New("Google login failed: Incorrect state")) + return ctx.Error(http.StatusUnauthorized, "Authorization not allowed for this session", errors.New("Google login failed: Incorrect state")) } // Handle the exchange code to initiate a transport token, err := conf.Exchange(oauth2.NoContext, ctx.Query("code")) + if err != nil { return ctx.Error(http.StatusBadRequest, "Could not obtain OAuth token", err) } @@ -51,14 +66,30 @@ func EnableGoogleLogin(app *aero.Application) { client := conf.Client(oauth2.NoContext, token) resp, err := client.Get("https://www.googleapis.com/oauth2/v3/userinfo") + if err != nil { return ctx.Error(http.StatusBadRequest, "Failed requesting user data from Google", err) } - defer resp.Body.Close() - dataBytes, _ := ioutil.ReadAll(resp.Body) - data := string(dataBytes) - log.Println("Resp body: ", data) - return ctx.Text(data) + defer resp.Body.Close() + data, _ := ioutil.ReadAll(resp.Body) + + var googleUser GoogleUser + err = json.Unmarshal(data, &googleUser) + + if err != nil { + return ctx.Error(http.StatusBadRequest, "Failed parsing user data (JSON)", err) + } + + email := googleUser.Email + user, getErr := arn.GetUserByEmail(email) + + if getErr != nil { + return ctx.Error(http.StatusForbidden, "Email not registered", err) + } + + ctx.Session().Set("userId", user.ID) + + return ctx.Redirect("/") }) } diff --git a/jobs/airing-anime/airing-anime.go b/jobs/airing-anime/airing-anime.go index 92327535..e12e680e 100644 --- a/jobs/airing-anime/airing-anime.go +++ b/jobs/airing-anime/airing-anime.go @@ -1,6 +1,8 @@ package main import ( + "sort" + "github.com/animenotifier/arn" "github.com/fatih/color" ) @@ -16,7 +18,9 @@ func main() { return } - // sort.Slice + sort.Slice(animeList, func(i, j int) bool { + return animeList[i].StartDate > animeList[j].StartDate + }) // Convert to small anime list cache := &arn.ListOfIDs{} diff --git a/jobs/user-references/user-references.go b/jobs/user-references/user-references.go index 662f13b2..cd5798a2 100644 --- a/jobs/user-references/user-references.go +++ b/jobs/user-references/user-references.go @@ -10,6 +10,7 @@ func main() { // Delete Nick:User records arn.Truncate("NickToUser") + arn.Truncate("EmailToUser") // Get a stream of all anime allUsers, err := arn.AllUsers() @@ -24,7 +25,8 @@ func main() { count++ println(count, user.Nick) - user.ChangeNick(user.Nick) + user.SetNick(user.Nick) + user.SetEmail(user.Email) } color.Green("Finished.") diff --git a/pages/dashboard/dashboard.go b/pages/dashboard/dashboard.go index c4c4bb42..8cea2b96 100644 --- a/pages/dashboard/dashboard.go +++ b/pages/dashboard/dashboard.go @@ -1,7 +1,10 @@ package dashboard import ( + "net/http" + "github.com/aerogo/aero" + "github.com/animenotifier/arn" ) const maxPosts = 5 @@ -21,5 +24,17 @@ func Get(ctx *aero.Context) string { // } // return ctx.HTML(components.Dashboard(posts)) + userID := ctx.Session().GetString("userId") + + if userID != "" { + user, err := arn.GetUser(userID) + + if err != nil { + return ctx.Error(http.StatusInternalServerError, "Error fetching user data", err) + } + + return ctx.HTML("Welcome back, " + user.Nick + "!") + } + return ctx.HTML("ARN 4.0 is currently under construction.
Support the development
Login via Google") }