package main import ( "encoding/hex" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "time" _ "github.com/lib/pq" ) type User struct { Id int Type string OpId string `json:"sub"` Name string `json:"given_name"` Email string `json:"email"` LfmName string LfmPassword string } type UserSession struct { Id string UserId int UserName string } func (app *App) login(w http.ResponseWriter, r *http.Request) { state := hex.EncodeToString(genKey(32)) if err := app.SetCookie(w, "state", state, 120); err != nil { log.Panic(err) } url := app.Config.OAuth.AuthCodeURL(state) app.Template.ExecuteTemplate(w, "login.tmpl", url) } func (app *App) root(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } se := new(UserSession) err := app.GetCookie(r, "session", se) if err != nil { http.Redirect(w, r, "/login", http.StatusFound) return } scrobbles := app.RecentScrobbles(se.UserId) np := app.NowPlaying(se.UserId) np.Image = "static/np2.gif" if time.Since(np.Time) > time.Duration(np.Duration)*time.Second { np = nil } app.Template.ExecuteTemplate(w, "index.tmpl", struct { Session *UserSession Scrobbles []*Scrobble NowPlaying *Scrobble }{se, scrobbles, np}) } func (app *App) callback(w http.ResponseWriter, r *http.Request) { defer func() { if rec := recover(); rec != nil { http.Redirect(w, r, "/login", http.StatusFound) log.Println(rec) } }() var state string app.GetCookie(r, "state", &state) if state == "" || state != r.FormValue("state") { panic(fmt.Errorf("state")) } code := r.FormValue("code") tok, _ := app.Config.OAuth.Exchange(r.Context(), code) client := app.Config.OAuth.Client(r.Context(), tok) resp, _ := client.Get("https://www.googleapis.com/plus/v1/people/me/openIdConnect") p, _ := ioutil.ReadAll(resp.Body) user := &User{Type: "google"} json.Unmarshal(p, user) s := &UserSession{Id: hex.EncodeToString(genKey(32))} var newUser bool if err := app.GetUser(user); err != nil { newUser = true if err := app.InsertUser(user); err != nil { panic(err) } } s.UserId = user.Id s.UserName = user.Name app.InsertUserSession(s) app.SetCookie(w, "session", s, 86400*30) if newUser { http.Redirect(w, r, "/settings", http.StatusTemporaryRedirect) } else { http.Redirect(w, r, "/", http.StatusFound) } } func (app *App) settings(w http.ResponseWriter, r *http.Request) { se := new(UserSession) err := app.GetCookie(r, "session", se) if err != nil { http.Redirect(w, r, "/login", http.StatusFound) return } if r.Method == "POST" && r.FormValue("save") != "" { u := &User{ Id: se.UserId, Name: r.FormValue("name"), Email: r.FormValue("email"), LfmName: r.FormValue("lfm_name"), } if password := r.FormValue("lfm_password"); password != "" { u.LfmPassword = md5hex(password) } if err := app.SaveUser(u); err != nil { log.Println(err) } se.UserName = u.Name app.SetCookie(w, "session", se, 86400*30) } if r.Method == "POST" && r.FormValue("import") != "" { u := &User{ Id: se.UserId, } app.GetUser(u) go app.ImportRecentTracks(u) } user := &User{Id: se.UserId} if err := app.GetUser(user); err != nil { log.Println(err) } li, ct, err := app.ImportStats(user.Id) err = app.Template.ExecuteTemplate(w, "settings.tmpl", struct { Session *UserSession *User LastImport time.Time ImportCount int }{Session: se, User: user, LastImport: li, ImportCount: ct}) if err != nil { log.Println(err) } }