1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package main
import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
_ "github.com/lib/pq"
)
type UserInfo struct {
Sub string `json:"sub"`
UserName string `json:"given_name"`
Email string `json:"email"`
}
type UserSession struct {
Id string
UserId int
UserName string
}
func (app *App) login(w http.ResponseWriter, r *http.Request) {
state := hex.EncodeToString(genKey(32))
app.SetCookie(w, "state", state, 120)
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)
app.Template.ExecuteTemplate(w, "index.tmpl", struct {
Session *UserSession
Scrobbles []*Scrobble
}{se, scrobbles})
}
func (app *App) callback(w http.ResponseWriter, r *http.Request) {
redir := func(err error) {
if err != nil {
http.Redirect(w, r, "/login", http.StatusFound)
log.Panic(err)
}
}
var state string
app.GetCookie(r, "state", &state)
if state == "" || state != r.FormValue("state") {
redir(fmt.Errorf("state"))
}
code := r.FormValue("code")
tok, err := app.Config.OAuth.Exchange(context.Background(), code)
redir(err)
client := app.Config.OAuth.Client(context.Background(), tok)
resp, _ := client.Get("https://www.googleapis.com/plus/v1/people/me/openIdConnect")
p, _ := ioutil.ReadAll(resp.Body)
userinfo := new(UserInfo)
err = json.Unmarshal(p, userinfo)
redir(err)
se := new(UserSession)
se.Id = hex.EncodeToString(genKey(32))
row := app.DB.QueryRow("SELECT user_id, name FROM users WHERE type='google' AND op_id=$1",
userinfo.Sub)
err = row.Scan(&se.UserId, &se.UserName)
if err != nil {
row := app.DB.QueryRow("INSERT into users (type, op_id, name, email)"+
"values ('google', $1, $2, $3) RETURNING user_id",
userinfo.Sub, userinfo.UserName, userinfo.Email)
row.Scan(&se.UserId)
se.UserName = userinfo.UserName
}
app.DB.Exec("INSERT into user_sessions values ($1, $2)", se.Id, se.UserId)
app.SetCookie(w, "session", se, 86400*30)
if err != nil {
http.Redirect(w, r, "/settings", http.StatusTemporaryRedirect)
return
}
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" {
_, err = app.DB.Exec("UPDATE users SET name=$1, email=$2, lfm_name=$3, lfm_password=$4 WHERE user_id=$5",
r.FormValue("name"), r.FormValue("email"), r.FormValue("lfm_name"),
md5hex(r.FormValue("lfm_password")), se.UserId)
if err != nil {
log.Println(err)
}
se.UserName = r.FormValue("name")
app.SetCookie(w, "session", se, 86400*30)
}
var userName, email, lfmName, lfmPassword string
row := app.DB.QueryRow("SELECT name, email, lfm_name, lfm_password FROM users WHERE user_id=$1",
se.UserId)
row.Scan(&userName, &email, &lfmName, &lfmPassword)
app.Template.ExecuteTemplate(w, "settings.tmpl", struct {
Session *UserSession
UserName string
Email string
LfmName string
LfmPassword string
}{se, userName, email, lfmName, lfmPassword})
}
|