diff --git a/auth/google.go b/auth/google.go index 8110020a..5e9bc99b 100644 --- a/auth/google.go +++ b/auth/google.go @@ -92,6 +92,13 @@ func InstallGoogleAuth(app *aero.Application) { user, getErr := arn.GetUserFromTable("GoogleToUser", googleUser.Sub) if getErr == nil && user != nil { + // Add GoogleToUser reference + user.Accounts.Google.ID = googleUser.Sub + arn.DB.Set("GoogleToUser", googleUser.Sub, &arn.GoogleToUser{ + ID: googleUser.Sub, + UserID: user.ID, + }) + session.Set("userId", user.ID) return ctx.Redirect("/") } @@ -104,6 +111,18 @@ func InstallGoogleAuth(app *aero.Application) { return ctx.Redirect("/") } - return ctx.Error(http.StatusForbidden, "Account does not exist", getErr) + user = arn.NewUser() + user.Nick = "g" + googleUser.Sub + user.Email = googleUser.Email + user.FirstName = googleUser.GivenName + user.LastName = googleUser.FamilyName + user.Gender = googleUser.Gender + user.Accounts.Google.ID = googleUser.Sub + user.LastLogin = arn.DateTimeUTC() + + arn.PrettyPrint(user) + // arn.RegisterUser(user) + + return ctx.Error(http.StatusForbidden, "Account does not exist", nil) }) } diff --git a/main.go b/main.go index 4e277623..4dfe6162 100644 --- a/main.go +++ b/main.go @@ -77,6 +77,7 @@ func configure(app *aero.Application) *aero.Application { // Middleware app.Use(middleware.Log()) app.Use(middleware.Session()) + app.Use(middleware.UserInfo()) // API api := api.New("/api/", arn.DB) diff --git a/middleware/UserInfo.go b/middleware/UserInfo.go new file mode 100644 index 00000000..f016a48f --- /dev/null +++ b/middleware/UserInfo.go @@ -0,0 +1,99 @@ +package middleware + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/utils" + "github.com/fatih/color" + "github.com/mssola/user_agent" + "github.com/parnurzeal/gorequest" +) + +var apiKeys arn.APIKeys + +func init() { + data, _ := ioutil.ReadFile("security/api-keys.json") + err := json.Unmarshal(data, &apiKeys) + + if err != nil { + panic(err) + } +} + +// UserInfo updates user related information after each request. +func UserInfo() aero.Middleware { + return func(ctx *aero.Context, next func()) { + next() + + // This works asynchronously so it doesn't block the response + go updateUserInfo(ctx) + } +} + +// updateUserInfo is started asynchronously so it doesn't block the request +func updateUserInfo(ctx *aero.Context) { + user := utils.GetUser(ctx) + + // When there's no user logged in, nothing to update + if user == nil { + return + } + + // Ignore non-HTML requests + println(ctx.GetRequestHeader("Accept-Type")) + if strings.Index(ctx.GetRequestHeader("Accept-Type"), "text/html") == -1 { + return + } + + newIP := ctx.RealIP() + newUserAgent := ctx.UserAgent() + + if user.UserAgent != newUserAgent { + user.UserAgent = newUserAgent + + // Parse user agent + parsed := user_agent.New(user.UserAgent) + + // Browser + user.Browser.Name, user.Browser.Version = parsed.Browser() + + arn.PrettyPrint(user.Browser) + + // OS + os := parsed.OSInfo() + user.OS.Name = os.Name + user.OS.Version = os.Version + + arn.PrettyPrint(user.OS) + } + + if user.IP != newIP { + user.IP = newIP + locationAPI := "https://api.ipinfodb.com/v3/ip-city/?key=" + apiKeys.IPInfoDB.ID + "&ip=" + "2a02:8108:8dc0:3000:6cf1:af03:ce6e:679a" + "&format=json" + + response, data, err := gorequest.New().Get(locationAPI).EndBytes() + + if len(err) > 0 && err[0] != nil { + color.Red(err[0].Error()) + return + } + + if response.StatusCode != http.StatusOK { + body, _ := ioutil.ReadAll(response.Body) + fmt.Println(response.StatusCode, locationAPI) + fmt.Println(string(body)) + return + } + + json.Unmarshal(data, &user.Location) + arn.PrettyPrint(user.Location) + } + + // user.Save() +}