From ef0f45527a47844c1c8db005044cd9ae05b761e6 Mon Sep 17 00:00:00 2001 From: Adhityaa Date: Wed, 20 Jun 2018 08:59:55 +0530 Subject: [PATCH] everywhere: use different session cookie names If the user is hosting the dashboard in the same domain as their blog (with a nginx suburi, for example), the two session cookies clash; logging into one service logs you out of the other. With this patch, both have separate names. Fixes https://gitlab.com/commento/commento-ce/issues/49 --- api/comment_approve.go | 4 +- api/comment_delete.go | 4 +- api/comment_list.go | 8 +-- api/comment_new.go | 6 +-- api/comment_vote.go | 6 +-- api/commenter_get.go | 12 ++--- api/commenter_get_test.go | 18 +++---- api/commenter_login.go | 18 +++---- api/commenter_login_test.go | 4 +- api/commenter_self.go | 4 +- api/commenter_session.go | 5 +- api/commenter_session_get.go | 25 ---------- api/commenter_session_get_test.go | 46 ------------------ api/commenter_session_new.go | 22 ++++----- api/commenter_session_new_test.go | 6 +-- api/commenter_session_update.go | 12 ++--- api/commenter_session_update_test.go | 8 +-- api/database_migrations.go | 6 ++- api/domain_delete.go | 4 +- api/domain_import_disqus.go | 4 +- api/domain_list.go | 4 +- api/domain_moderator_delete.go | 4 +- api/domain_moderator_new.go | 4 +- api/domain_new.go | 4 +- api/domain_statistics.go | 4 +- api/domain_update.go | 4 +- api/errors.go | 4 +- api/oauth_google_callback.go | 8 +-- api/oauth_google_redirect.go | 8 +-- api/owner_get.go | 8 +-- api/owner_get_test.go | 14 +++--- api/owner_login.go | 18 +++---- api/owner_login_test.go | 4 +- api/owner_self.go | 24 ++++----- api/owner_self_test.go | 32 ------------ api/router_api.go | 2 +- db/20180620083655-session-token-renamme.sql | 5 ++ frontend/js/commento.js | 54 ++++++++++----------- frontend/js/dashboard-domain.js | 16 +++--- frontend/js/dashboard-import.js | 6 +-- frontend/js/dashboard-moderation.js | 12 ++--- frontend/js/dashboard-statistics.js | 4 +- frontend/js/login.js | 2 +- frontend/js/logout.js | 2 +- frontend/js/self.js | 2 +- 45 files changed, 189 insertions(+), 282 deletions(-) delete mode 100644 api/commenter_session_get.go delete mode 100644 api/commenter_session_get_test.go delete mode 100644 api/owner_self_test.go create mode 100644 db/20180620083655-session-token-renamme.sql diff --git a/api/comment_approve.go b/api/comment_approve.go index 28b96d4..d39fa58 100644 --- a/api/comment_approve.go +++ b/api/comment_approve.go @@ -26,7 +26,7 @@ func commentApprove(commentHex string) error { func commentApproveHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + CommenterToken *string `json:"commenterToken"` CommentHex *string `json:"commentHex"` } @@ -36,7 +36,7 @@ func commentApproveHandler(w http.ResponseWriter, r *http.Request) { return } - c, err := commenterGetBySession(*x.Session) + c, err := commenterGetByCommenterToken(*x.CommenterToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/comment_delete.go b/api/comment_delete.go index b12e6e5..d7af088 100644 --- a/api/comment_delete.go +++ b/api/comment_delete.go @@ -25,7 +25,7 @@ func commentDelete(commentHex string) error { func commentDeleteHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + CommenterToken *string `json:"commenterToken"` CommentHex *string `json:"commentHex"` } @@ -35,7 +35,7 @@ func commentDeleteHandler(w http.ResponseWriter, r *http.Request) { return } - c, err := commenterGetBySession(*x.Session) + c, err := commenterGetByCommenterToken(*x.CommenterToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/comment_list.go b/api/comment_list.go index 3042dba..f59f7c3 100644 --- a/api/comment_list.go +++ b/api/comment_list.go @@ -91,7 +91,7 @@ func commentList(commenterHex string, domain string, path string, includeUnappro func commentListHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + CommenterToken *string `json:"CommenterToken"` Domain *string `json:"domain"` Path *string `json:"path"` } @@ -113,10 +113,10 @@ func commentListHandler(w http.ResponseWriter, r *http.Request) { commenterHex := "anonymous" isModerator := false - if *x.Session != "anonymous" { - c, err := commenterGetBySession(*x.Session) + if *x.CommenterToken != "anonymous" { + c, err := commenterGetByCommenterToken(*x.CommenterToken) if err != nil { - if err == errorNoSuchSession { + if err == errorNoSuchToken { commenterHex = "anonymous" } else { writeBody(w, response{"success": false, "message": err.Error()}) diff --git a/api/comment_new.go b/api/comment_new.go index b832814..7af2296 100644 --- a/api/comment_new.go +++ b/api/comment_new.go @@ -36,7 +36,7 @@ func commentNew(commenterHex string, domain string, path string, parentHex strin func commentNewHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + CommenterToken *string `json:"commenterToken"` Domain *string `json:"domain"` Path *string `json:"path"` ParentHex *string `json:"parentHex"` @@ -74,11 +74,11 @@ func commentNewHandler(w http.ResponseWriter, r *http.Request) { var commenterHex string var state string - if *x.Session == "anonymous" { + if *x.CommenterToken == "anonymous" { state = "unapproved" commenterHex = "anonymous" } else { - c, err := commenterGetBySession(*x.Session) + c, err := commenterGetByCommenterToken(*x.CommenterToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/comment_vote.go b/api/comment_vote.go index 3cebf6d..46fd6ef 100644 --- a/api/comment_vote.go +++ b/api/comment_vote.go @@ -45,7 +45,7 @@ func commentVote(commenterHex string, commentHex string, direction int) error { func commentVoteHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + CommenterToken *string `json:"commenterToken"` CommentHex *string `json:"commentHex"` Direction *int `json:"direction"` } @@ -56,12 +56,12 @@ func commentVoteHandler(w http.ResponseWriter, r *http.Request) { return } - if *x.Session == "anonymous" { + if *x.CommenterToken == "anonymous" { writeBody(w, response{"success": false, "message": errorUnauthorisedVote.Error()}) return } - c, err := commenterGetBySession(*x.Session) + c, err := commenterGetByCommenterToken(*x.CommenterToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/commenter_get.go b/api/commenter_get.go index 7e86878..ca3bd39 100644 --- a/api/commenter_get.go +++ b/api/commenter_get.go @@ -44,26 +44,26 @@ func commenterGetByEmail(provider string, email string) (commenter, error) { return c, nil } -func commenterGetBySession(session string) (commenter, error) { - if session == "" { +func commenterGetByCommenterToken(commenterToken string) (commenter, error) { + if commenterToken == "" { return commenter{}, errorMissingField } statement := ` SELECT commenterHex FROM commenterSessions - WHERE session = $1; + WHERE commenterToken = $1; ` - row := db.QueryRow(statement, session) + row := db.QueryRow(statement, commenterToken) var commenterHex string if err := row.Scan(&commenterHex); err != nil { // TODO: is the only error? - return commenter{}, errorNoSuchSession + return commenter{}, errorNoSuchToken } if commenterHex == "none" { - return commenter{}, errorNoSuchSession + return commenter{}, errorNoSuchToken } return commenterGetByHex(commenterHex) diff --git a/api/commenter_get_test.go b/api/commenter_get_test.go index af0b776..50cb2bf 100644 --- a/api/commenter_get_test.go +++ b/api/commenter_get_test.go @@ -30,16 +30,16 @@ func TestCommenterGetByHexEmpty(t *testing.T) { } } -func TestCommenterGetBySession(t *testing.T) { +func TestCommenterGetByCommenterToken(t *testing.T) { failTestOnError(t, setupTestEnv()) commenterHex, _ := commenterNew("test@example.com", "Test", "undefined", "https://example.com/photo.jpg", "google", "") - session, _ := commenterSessionNew() + commenterToken, _ := commenterTokenNew() - commenterSessionUpdate(session, commenterHex) + commenterSessionUpdate(commenterToken, commenterHex) - c, err := commenterGetBySession(session) + c, err := commenterGetByCommenterToken(commenterToken) if err != nil { t.Errorf("unexpected error getting commenter by hex: %v", err) return @@ -51,11 +51,11 @@ func TestCommenterGetBySession(t *testing.T) { } } -func TestCommenterGetBySessionEmpty(t *testing.T) { +func TestCommenterGetByCommenterTokenEmpty(t *testing.T) { failTestOnError(t, setupTestEnv()) - if _, err := commenterGetBySession(""); err == nil { - t.Errorf("expected error not found getting commenter with empty session") + if _, err := commenterGetByCommenterToken(""); err == nil { + t.Errorf("expected error not found getting commenter with empty commenterToken") return } } @@ -65,9 +65,9 @@ func TestCommenterGetByName(t *testing.T) { commenterHex, _ := commenterNew("test@example.com", "Test", "undefined", "https://example.com/photo.jpg", "google", "") - session, _ := commenterSessionNew() + commenterToken, _ := commenterTokenNew() - commenterSessionUpdate(session, commenterHex) + commenterSessionUpdate(commenterToken, commenterHex) c, err := commenterGetByEmail("google", "test@example.com") if err != nil { diff --git a/api/commenter_login.go b/api/commenter_login.go index f42229a..c9996d5 100644 --- a/api/commenter_login.go +++ b/api/commenter_login.go @@ -29,24 +29,24 @@ func commenterLogin(email string, password string) (string, error) { return "", errorInvalidEmailPassword } - session, err := randomHex(32) + commenterToken, err := randomHex(32) if err != nil { - logger.Errorf("cannot create session hex: %v", err) + logger.Errorf("cannot create commenterToken: %v", err) return "", errorInternal } statement = ` INSERT INTO - commenterSessions (session, commenterHex, creationDate) - VALUES ($1, $2, $3 ); + commenterSessions (commenterToken, commenterHex, creationDate) + VALUES ($1, $2, $3 ); ` - _, err = db.Exec(statement, session, commenterHex, time.Now().UTC()) + _, err = db.Exec(statement, commenterToken, commenterHex, time.Now().UTC()) if err != nil { - logger.Errorf("cannot insert session token: %v\n", err) + logger.Errorf("cannot insert commenterToken token: %v\n", err) return "", errorInternal } - return session, nil + return commenterToken, nil } func commenterLoginHandler(w http.ResponseWriter, r *http.Request) { @@ -61,11 +61,11 @@ func commenterLoginHandler(w http.ResponseWriter, r *http.Request) { return } - session, err := commenterLogin(*x.Email, *x.Password) + commenterToken, err := commenterLogin(*x.Email, *x.Password) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return } - writeBody(w, response{"success": true, "session": session}) + writeBody(w, response{"success": true, "commenterToken": commenterToken}) } diff --git a/api/commenter_login_test.go b/api/commenter_login_test.go index 8d43d03..0ce1457 100644 --- a/api/commenter_login_test.go +++ b/api/commenter_login_test.go @@ -24,8 +24,8 @@ func TestCommenterLoginBasics(t *testing.T) { return } - if session, err := commenterLogin("test@example.com", "hunter2"); session == "" { - t.Errorf("empty session on successful login: %v", err) + if commenterToken, err := commenterLogin("test@example.com", "hunter2"); commenterToken == "" { + t.Errorf("empty comenterToken on successful login: %v", err) return } } diff --git a/api/commenter_self.go b/api/commenter_self.go index 804563d..632b025 100644 --- a/api/commenter_self.go +++ b/api/commenter_self.go @@ -6,7 +6,7 @@ import ( func commenterSelfHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + CommenterToken *string `json:"commenterToken"` } var x request @@ -15,7 +15,7 @@ func commenterSelfHandler(w http.ResponseWriter, r *http.Request) { return } - c, err := commenterGetBySession(*x.Session) + c, err := commenterGetByCommenterToken(*x.CommenterToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/commenter_session.go b/api/commenter_session.go index 77c933e..0fe3419 100644 --- a/api/commenter_session.go +++ b/api/commenter_session.go @@ -4,8 +4,11 @@ import ( "time" ) +// A session is a 3-field entry of a token, a hex, and a creation date. Do +// not confuse session and token; the token is just an identifying string, +// while the session contains more information. type commenterSession struct { - Session string `json:"session"` + CommenterToken string `json:"commenterToken"` CommenterHex string `json:"commenterHex"` CreationDate time.Time `json:"creationDate"` } diff --git a/api/commenter_session_get.go b/api/commenter_session_get.go deleted file mode 100644 index ae9731e..0000000 --- a/api/commenter_session_get.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import () - -func commenterSessionGet(session string) (commenterSession, error) { - if session == "" { - return commenterSession{}, errorMissingField - } - - statement := ` - SELECT commenterHex, creationDate - FROM commenterSessions - WHERE session=$1; - ` - row := db.QueryRow(statement, session) - - cs := commenterSession{} - if err := row.Scan(&cs.CommenterHex, &cs.CreationDate); err != nil { - return commenterSession{}, errorNoSuchSession - } - - cs.Session = session - - return cs, nil -} diff --git a/api/commenter_session_get_test.go b/api/commenter_session_get_test.go deleted file mode 100644 index 7523901..0000000 --- a/api/commenter_session_get_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "testing" -) - -func TestCommenterSessionGetBasics(t *testing.T) { - failTestOnError(t, setupTestEnv()) - - commenterHex, _ := commenterNew("test@example.com", "Test", "undefined", "https://example.com/photo.jpg", "google", "") - - session, _ := commenterSessionNew() - - commenterSessionUpdate(session, commenterHex) - - cs, err := commenterSessionGet(session) - if err != nil { - t.Errorf("unexpected error found when getting session information: %v", err) - return - } - - if cs.CommenterHex != commenterHex { - t.Errorf("expected commenterHex=%s got commenterHex=%s", commenterHex, cs.CommenterHex) - return - } -} - -func TestCommenterSessionGetDNE(t *testing.T) { - failTestOnError(t, setupTestEnv()) - - _, err := commenterSessionGet("does-not-exist") - if err == nil { - t.Errorf("expected error not found when invalid session") - return - } -} - -func TestCommenterSessionGetEmpty(t *testing.T) { - failTestOnError(t, setupTestEnv()) - - _, err := commenterSessionGet("") - if err == nil { - t.Errorf("expected error not found with empty session") - return - } -} diff --git a/api/commenter_session_new.go b/api/commenter_session_new.go index eba6581..59f4a5e 100644 --- a/api/commenter_session_new.go +++ b/api/commenter_session_new.go @@ -5,33 +5,33 @@ import ( "time" ) -func commenterSessionNew() (string, error) { - session, err := randomHex(32) +func commenterTokenNew() (string, error) { + commenterToken, err := randomHex(32) if err != nil { - logger.Errorf("cannot create session hex: %v", err) + logger.Errorf("cannot create commenterToken: %v", err) return "", errorInternal } statement := ` INSERT INTO - commenterSessions (session, creationDate) - VALUES ($1, $2 ); + commenterSessions (commenterToken, creationDate) + VALUES ($1, $2 ); ` - _, err = db.Exec(statement, session, time.Now().UTC()) + _, err = db.Exec(statement, commenterToken, time.Now().UTC()) if err != nil { - logger.Errorf("cannot insert new session: %v", err) + logger.Errorf("cannot insert new commenterToken: %v", err) return "", errorInternal } - return session, nil + return commenterToken, nil } -func commenterSessionNewHandler(w http.ResponseWriter, r *http.Request) { - session, err := commenterSessionNew() +func commenterTokenNewHandler(w http.ResponseWriter, r *http.Request) { + commenterToken, err := commenterTokenNew() if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return } - writeBody(w, response{"success": true, "session": session}) + writeBody(w, response{"success": true, "commenterToken": commenterToken}) } diff --git a/api/commenter_session_new_test.go b/api/commenter_session_new_test.go index e058107..20eb9fe 100644 --- a/api/commenter_session_new_test.go +++ b/api/commenter_session_new_test.go @@ -4,11 +4,11 @@ import ( "testing" ) -func TestCommenterSessionNewBasics(t *testing.T) { +func TestCommenterTokenNewBasics(t *testing.T) { failTestOnError(t, setupTestEnv()) - if _, err := commenterSessionNew(); err != nil { - t.Errorf("unexpected error creating new session: %v", err) + if _, err := commenterTokenNew(); err != nil { + t.Errorf("unexpected error creating new commenterToken: %v", err) return } } diff --git a/api/commenter_session_update.go b/api/commenter_session_update.go index a9ffb7c..f480d46 100644 --- a/api/commenter_session_update.go +++ b/api/commenter_session_update.go @@ -2,19 +2,19 @@ package main import () -func commenterSessionUpdate(session string, commenterHex string) error { - if session == "" || commenterHex == "" { +func commenterSessionUpdate(commenterToken string, commenterHex string) error { + if commenterToken == "" || commenterHex == "" { return errorMissingField } statement := ` UPDATE commenterSessions - SET commenterHex=$2 - WHERE session=$1; + SET commenterHex = $2 + WHERE commenterToken = $1; ` - _, err := db.Exec(statement, session, commenterHex) + _, err := db.Exec(statement, commenterToken, commenterHex) if err != nil { - logger.Errorf("error updating commenterHex in commenterSessions: %v", err) + logger.Errorf("error updating commenterHex: %v", err) return errorInternal } diff --git a/api/commenter_session_update_test.go b/api/commenter_session_update_test.go index cdea0af..9d27bc6 100644 --- a/api/commenter_session_update_test.go +++ b/api/commenter_session_update_test.go @@ -7,10 +7,10 @@ import ( func TestCommenterSessionUpdateBasics(t *testing.T) { failTestOnError(t, setupTestEnv()) - session, _ := commenterSessionNew() + commenterToken, _ := commenterTokenNew() - if err := commenterSessionUpdate(session, "temp-commenter-hex"); err != nil { - t.Errorf("unexpected error updating session to commenterHex: %v", err) + if err := commenterSessionUpdate(commenterToken, "temp-commenter-hex"); err != nil { + t.Errorf("unexpected error updating commenter session: %v", err) return } } @@ -19,7 +19,7 @@ func TestCommenterSessionUpdateEmpty(t *testing.T) { failTestOnError(t, setupTestEnv()) if err := commenterSessionUpdate("", "temp-commenter-hex"); err == nil { - t.Errorf("expected error not found when updating with empty session") + t.Errorf("expected error not found when updating with empty commenterToken") return } } diff --git a/api/database_migrations.go b/api/database_migrations.go index 1d48d49..f625203 100644 --- a/api/database_migrations.go +++ b/api/database_migrations.go @@ -40,6 +40,8 @@ func performMigrationsFromDir(dir string) error { filenames[filename] = true } + logger.Infof("%d migrations already installed, looking for more", len(filenames)) + completed := 0 for _, file := range files { if strings.HasSuffix(file.Name(), ".sql") { @@ -73,7 +75,9 @@ func performMigrationsFromDir(dir string) error { } if completed > 0 { - logger.Infof("%d migrations found, %d new migrations completed (%d total)", len(filenames), completed, len(filenames)+completed) + logger.Infof("%d new migrations completed (%d total)", completed, len(filenames)+completed) + } else { + logger.Infof("none found") } return nil diff --git a/api/domain_delete.go b/api/domain_delete.go index b8be4a0..270500a 100644 --- a/api/domain_delete.go +++ b/api/domain_delete.go @@ -65,7 +65,7 @@ func domainDelete(domain string) error { func domainDeleteHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` Domain *string `json:"domain"` } @@ -75,7 +75,7 @@ func domainDeleteHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_import_disqus.go b/api/domain_import_disqus.go index 6ec527b..d17834a 100644 --- a/api/domain_import_disqus.go +++ b/api/domain_import_disqus.go @@ -168,7 +168,7 @@ func domainImportDisqus(domain string, url string) (int, error) { func domainImportDisqusHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` Domain *string `json:"domain"` URL *string `json:"url"` } @@ -179,7 +179,7 @@ func domainImportDisqusHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_list.go b/api/domain_list.go index 8752a8c..fd4dd46 100644 --- a/api/domain_list.go +++ b/api/domain_list.go @@ -42,7 +42,7 @@ func domainList(ownerHex string) ([]domain, error) { func domainListHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` } var x request @@ -51,7 +51,7 @@ func domainListHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_moderator_delete.go b/api/domain_moderator_delete.go index ae56491..0af727d 100644 --- a/api/domain_moderator_delete.go +++ b/api/domain_moderator_delete.go @@ -24,7 +24,7 @@ func domainModeratorDelete(domain string, email string) error { func domainModeratorDeleteHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` Domain *string `json:"domain"` Email *string `json:"email"` } @@ -35,7 +35,7 @@ func domainModeratorDeleteHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_moderator_new.go b/api/domain_moderator_new.go index 2ce2d6b..91caa59 100644 --- a/api/domain_moderator_new.go +++ b/api/domain_moderator_new.go @@ -26,7 +26,7 @@ func domainModeratorNew(domain string, email string) error { func domainModeratorNewHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` Domain *string `json:"domain"` Email *string `json:"email"` } @@ -37,7 +37,7 @@ func domainModeratorNewHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_new.go b/api/domain_new.go index 6e39deb..a6323ce 100644 --- a/api/domain_new.go +++ b/api/domain_new.go @@ -26,7 +26,7 @@ func domainNew(ownerHex string, name string, domain string) error { func domainNewHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` Name *string `json:"name"` Domain *string `json:"domain"` } @@ -37,7 +37,7 @@ func domainNewHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_statistics.go b/api/domain_statistics.go index eb6a7b3..62241db 100644 --- a/api/domain_statistics.go +++ b/api/domain_statistics.go @@ -39,7 +39,7 @@ func domainStatistics(domain string) ([]int64, error) { func domainStatisticsHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` Domain *string `json:"domain"` } @@ -49,7 +49,7 @@ func domainStatisticsHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/domain_update.go b/api/domain_update.go index 0517478..4392990 100644 --- a/api/domain_update.go +++ b/api/domain_update.go @@ -22,7 +22,7 @@ func domainUpdate(d domain) error { func domainUpdateHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` D *domain `json:"domain"` } @@ -32,7 +32,7 @@ func domainUpdateHandler(w http.ResponseWriter, r *http.Request) { return } - o, err := ownerGetBySession(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return diff --git a/api/errors.go b/api/errors.go index c4834f6..408c9e8 100644 --- a/api/errors.go +++ b/api/errors.go @@ -17,7 +17,7 @@ var errorNoSuchConfirmationToken = errors.New("This email confirmation link has var errorNoSuchResetToken = errors.New("This password reset link has expired.") var errorNotAuthorised = errors.New("You're not authorised to access that.") var errorEmailAlreadyExists = errors.New("That email address has already been registered.") -var errorNoSuchSession = errors.New("No such session/state.") +var errorNoSuchToken = errors.New("No such session token.") var errorNoSuchCommenter = errors.New("No such commenter.") var errorAlreadyUpvoted = errors.New("You have already upvoted that comment.") var errorNoSuchDomain = errors.New("This domain is not registered with Commento.") @@ -32,8 +32,6 @@ var errorForbiddenEdit = errors.New("You cannot edit someone else's comment.") var errorMissingSmtpAddress = errors.New("Missing SMTP_FROM_ADDRESS") var errorSmtpNotConfigured = errors.New("SMTP is not configured.") var errorOauthMisconfigured = errors.New("OAuth is misconfigured.") -var errorUnassociatedSession = errors.New("No user associated with that session.") -var errorSessionAlreadyInUse = errors.New("Session is already in use.") var errorCannotReadResponse = errors.New("Cannot read response.") var errorNotModerator = errors.New("You need to be a moderator to do that.") var errorNotADirectory = errors.New("The given path is not a directory.") diff --git a/api/oauth_google_callback.go b/api/oauth_google_callback.go index e2b9397..e647281 100644 --- a/api/oauth_google_callback.go +++ b/api/oauth_google_callback.go @@ -9,11 +9,11 @@ import ( ) func googleCallbackHandler(w http.ResponseWriter, r *http.Request) { - session := r.FormValue("state") + commenterToken := r.FormValue("state") code := r.FormValue("code") - _, err := commenterSessionGet(session) - if err != nil && err != errorNoSuchSession { + _, err := commenterGetByCommenterToken(commenterToken) + if err != nil && err != errorNoSuchToken { fmt.Fprintf(w, "Error: %s\n", err.Error()) return } @@ -73,7 +73,7 @@ func googleCallbackHandler(w http.ResponseWriter, r *http.Request) { commenterHex = c.CommenterHex } - if err := commenterSessionUpdate(session, commenterHex); err != nil { + if err := commenterSessionUpdate(commenterToken, commenterHex); err != nil { fmt.Fprintf(w, "Error: %s", err.Error()) return } diff --git a/api/oauth_google_redirect.go b/api/oauth_google_redirect.go index c81fa98..940ba85 100644 --- a/api/oauth_google_redirect.go +++ b/api/oauth_google_redirect.go @@ -12,14 +12,14 @@ func googleRedirectHandler(w http.ResponseWriter, r *http.Request) { return } - session := r.FormValue("session") + commenterToken := r.FormValue("commenterToken") - _, err := commenterGetBySession(session) - if err != nil && err != errorNoSuchSession { + _, err := commenterGetByCommenterToken(commenterToken) + if err != nil && err != errorNoSuchToken { fmt.Fprintf(w, "error: %s\n", err.Error()) return } - url := googleConfig.AuthCodeURL(session) + url := googleConfig.AuthCodeURL(commenterToken) http.Redirect(w, r, url, http.StatusFound) } diff --git a/api/owner_get.go b/api/owner_get.go index 607a621..f916693 100644 --- a/api/owner_get.go +++ b/api/owner_get.go @@ -23,8 +23,8 @@ func ownerGetByEmail(email string) (owner, error) { return o, nil } -func ownerGetBySession(session string) (owner, error) { - if session == "" { +func ownerGetByOwnerToken(ownerToken string) (owner, error) { + if ownerToken == "" { return owner{}, errorMissingField } @@ -33,10 +33,10 @@ func ownerGetBySession(session string) (owner, error) { FROM owners WHERE email IN ( SELECT email FROM ownerSessions - WHERE session=$1 + WHERE ownerToken = $1 ); ` - row := db.QueryRow(statement, session) + row := db.QueryRow(statement, ownerToken) var o owner if err := row.Scan(&o.OwnerHex, &o.Email, &o.Name, &o.ConfirmedEmail, &o.JoinDate); err != nil { diff --git a/api/owner_get_test.go b/api/owner_get_test.go index 1972e3c..29da783 100644 --- a/api/owner_get_test.go +++ b/api/owner_get_test.go @@ -30,16 +30,16 @@ func TestOwnerGetByEmailDNE(t *testing.T) { } } -func TestOwnerGetBySessionBasics(t *testing.T) { +func TestOwnerGetByOwnerTokenBasics(t *testing.T) { failTestOnError(t, setupTestEnv()) ownerHex, _ := ownerNew("test@example.com", "Test", "hunter2") - session, _ := ownerLogin("test@example.com", "hunter2") + ownerToken, _ := ownerLogin("test@example.com", "hunter2") - o, err := ownerGetBySession(session) + o, err := ownerGetByOwnerToken(ownerToken) if err != nil { - t.Errorf("unexpected error on ownerGetBySession: %v", err) + t.Errorf("unexpected error on ownerGetByOwnerToken: %v", err) return } @@ -49,11 +49,11 @@ func TestOwnerGetBySessionBasics(t *testing.T) { } } -func TestOwnerGetBySessionDNE(t *testing.T) { +func TestOwnerGetByOwnerTokenDNE(t *testing.T) { failTestOnError(t, setupTestEnv()) - if _, err := ownerGetBySession("does-not-exist"); err == nil { - t.Errorf("expected error not found on ownerGetBySession before creating an account") + if _, err := ownerGetByOwnerToken("does-not-exist"); err == nil { + t.Errorf("expected error not found on ownerGetByOwnerToken before creating an account") return } } diff --git a/api/owner_login.go b/api/owner_login.go index 218c1ae..923907a 100644 --- a/api/owner_login.go +++ b/api/owner_login.go @@ -34,24 +34,24 @@ func ownerLogin(email string, password string) (string, error) { return "", errorInvalidEmailPassword } - session, err := randomHex(32) + ownerToken, err := randomHex(32) if err != nil { - logger.Errorf("cannot create session hex: %v", err) + logger.Errorf("cannot create ownerToken: %v", err) return "", errorInternal } statement = ` INSERT INTO - ownerSessions (session, ownerHex, loginDate) - VALUES ($1, $2, $3 ); + ownerSessions (ownerToken, ownerHex, loginDate) + VALUES ($1, $2, $3 ); ` - _, err = db.Exec(statement, session, ownerHex, time.Now().UTC()) + _, err = db.Exec(statement, ownerToken, ownerHex, time.Now().UTC()) if err != nil { - logger.Errorf("cannot insert session token: %v\n", err) + logger.Errorf("cannot insert ownerSession: %v\n", err) return "", errorInternal } - return session, nil + return ownerToken, nil } func ownerLoginHandler(w http.ResponseWriter, r *http.Request) { @@ -66,11 +66,11 @@ func ownerLoginHandler(w http.ResponseWriter, r *http.Request) { return } - session, err := ownerLogin(*x.Email, *x.Password) + ownerToken, err := ownerLogin(*x.Email, *x.Password) if err != nil { writeBody(w, response{"success": false, "message": err.Error()}) return } - writeBody(w, response{"success": true, "session": session}) + writeBody(w, response{"success": true, "ownerToken": ownerToken}) } diff --git a/api/owner_login_test.go b/api/owner_login_test.go index 282c52e..bb02037 100644 --- a/api/owner_login_test.go +++ b/api/owner_login_test.go @@ -24,8 +24,8 @@ func TestOwnerLoginBasics(t *testing.T) { return } - if session, err := ownerLogin("test@example.com", "hunter2"); session == "" { - t.Errorf("empty session on successful login: %v", err) + if ownerToken, err := ownerLogin("test@example.com", "hunter2"); ownerToken == "" { + t.Errorf("empty token on successful login: %v", err) return } } diff --git a/api/owner_self.go b/api/owner_self.go index 5a5d629..58cf5fe 100644 --- a/api/owner_self.go +++ b/api/owner_self.go @@ -4,18 +4,9 @@ import ( "net/http" ) -func ownerSelf(session string) (bool, owner) { - o, err := ownerGetBySession(session) - if err != nil { - return false, owner{} - } - - return true, o -} - func ownerSelfHandler(w http.ResponseWriter, r *http.Request) { type request struct { - Session *string `json:"session"` + OwnerToken *string `json:"ownerToken"` } var x request @@ -24,7 +15,16 @@ func ownerSelfHandler(w http.ResponseWriter, r *http.Request) { return } - loggedIn, o := ownerSelf(*x.Session) + o, err := ownerGetByOwnerToken(*x.OwnerToken) + if err == errorNoSuchToken { + writeBody(w, response{"success": true, "loggedIn": false}) + return + } - writeBody(w, response{"success": true, "loggedIn": loggedIn, "owner": o}) + if err != nil { + writeBody(w, response{"success": false, "message": err.Error()}) + return + } + + writeBody(w, response{"success": true, "loggedIn": true, "owner": o}) } diff --git a/api/owner_self_test.go b/api/owner_self_test.go deleted file mode 100644 index 20c4dd7..0000000 --- a/api/owner_self_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "testing" -) - -func TestOwnerSelfBasics(t *testing.T) { - failTestOnError(t, setupTestEnv()) - - ownerNew("test@example.com", "Test", "hunter2") - session, _ := ownerLogin("test@example.com", "hunter2") - - loggedIn, o := ownerSelf(session) - if !loggedIn { - t.Errorf("expected loggedIn=true got loggedIn=false") - return - } - - if o.Name != "Test" { - t.Errorf("expected name=Test got name=%s", o.Name) - return - } -} - -func TestOwnerSelfNotLoggedIn(t *testing.T) { - failTestOnError(t, setupTestEnv()) - - if loggedIn, _ := ownerSelf("does-not-exist"); loggedIn { - t.Errorf("expected loggedIn=false got loggedIn=true") - return - } -} diff --git a/api/router_api.go b/api/router_api.go index 5d96ec2..62d93f9 100644 --- a/api/router_api.go +++ b/api/router_api.go @@ -21,7 +21,7 @@ func initAPIRouter(router *mux.Router) error { router.HandleFunc("/api/domain/statistics", domainStatisticsHandler).Methods("POST") router.HandleFunc("/api/domain/import/disqus", domainImportDisqusHandler).Methods("POST") - router.HandleFunc("/api/commenter/session/new", commenterSessionNewHandler).Methods("GET") + router.HandleFunc("/api/commenter/token/new", commenterTokenNewHandler).Methods("GET") router.HandleFunc("/api/commenter/new", commenterNewHandler).Methods("POST") router.HandleFunc("/api/commenter/login", commenterLoginHandler).Methods("POST") router.HandleFunc("/api/commenter/self", commenterSelfHandler).Methods("POST") diff --git a/db/20180620083655-session-token-renamme.sql b/db/20180620083655-session-token-renamme.sql new file mode 100644 index 0000000..c576be5 --- /dev/null +++ b/db/20180620083655-session-token-renamme.sql @@ -0,0 +1,5 @@ +ALTER TABLE ownerSessions +RENAME COLUMN session TO ownerToken; + +ALTER TABLE commenterSessions +RENAME COLUMN session TO commenterToken diff --git a/frontend/js/commento.js b/frontend/js/commento.js index 376a62b..930da49 100644 --- a/frontend/js/commento.js +++ b/frontend/js/commento.js @@ -192,36 +192,36 @@ } - function sessionGet() { - var session = cookieGet("session"); - if (session === undefined) + function commenterTokenGet() { + var commenterToken = cookieGet("commenterToken"); + if (commenterToken === undefined) return "anonymous"; - return session; + return commenterToken; } global.logout = function() { - cookieSet("session", "anonymous"); + cookieSet("commenterToken", "anonymous"); refreshAll(); } function selfGet(callback) { - var session = sessionGet(); - if (session == "anonymous") { + var commenterToken = commenterTokenGet(); + if (commenterToken == "anonymous") { isAuthenticated = false; call(callback); return; } var json = { - session: sessionGet(), + "commenterToken": commenterTokenGet(), }; post(origin + "/api/commenter/self", json, function(resp) { if (!resp.success) { - cookieSet("session", "anonymous"); + cookieSet("commenterToken", "anonymous"); call(callback); return; } @@ -344,9 +344,9 @@ function commentsGet(callback) { var json = { - session: sessionGet(), - domain: location.host, - path: location.pathname, + "commenterToken": commenterTokenGet(), + "domain": location.host, + "path": location.pathname, }; post(origin + "/api/comment/list", json, function(resp) { @@ -487,7 +487,7 @@ } var json = { - "session": sessionGet(), + "commenterToken": commenterTokenGet(), "domain": location.host, "path": location.pathname, "parentHex": id, @@ -773,7 +773,7 @@ global.commentApprove = function(commentHex) { var json = { - "session": sessionGet(), + "commenterToken": commenterTokenGet(), "commentHex": commentHex, } @@ -796,7 +796,7 @@ global.commentDelete = function(commentHex) { var json = { - "session": sessionGet(), + "commenterToken": commenterTokenGet(), "commentHex": commentHex, } @@ -826,7 +826,7 @@ var score = $(ID_SCORE + commentHex); var json = { - "session": sessionGet(), + "commenterToken": commenterTokenGet(), "commentHex": commentHex, "direction": direction, }; @@ -970,7 +970,7 @@ global.commentoAuth = function(provider) { if (provider == "anonymous") { - cookieSet("session", "anonymous"); + cookieSet("commenterToken", "anonymous"); chosenAnonymous = true; refreshAll(); return; @@ -978,15 +978,15 @@ var popup = window.open("", "_blank"); - get(origin + "/api/commenter/session/new", function(resp) { + get(origin + "/api/commenter/token/new", function(resp) { if (!resp.success) { errorShow(resp.message); return; } - cookieSet("session", resp.session); + cookieSet("commenterToken", resp.commenterToken); - popup.location = origin + "/api/oauth/" + provider + "/redirect?session=" + resp.session; + popup.location = origin + "/api/oauth/" + provider + "/redirect?commenterToken=" + resp.commenterToken; var interval = setInterval(function() { if (popup.closed) { @@ -1144,8 +1144,8 @@ function loginUP(username, password) { var json = { - email: username, - password: password, + "email": username, + "password": password, }; post(origin + "/api/commenter/login", json, function(resp) { @@ -1155,7 +1155,7 @@ return } - cookieSet("session", resp.session); + cookieSet("commenterToken", resp.commenterToken); refreshAll(); }); } @@ -1176,10 +1176,10 @@ var password = $(ID_LOGIN_BOX_PASSWORD_INPUT); var json = { - email: email.value, - name: name.value, - website: website.value, - password: password.value, + "email": email.value, + "name": name.value, + "website": website.value, + "password": password.value, }; post(origin + "/api/commenter/new", json, function(resp) { diff --git a/frontend/js/dashboard-domain.js b/frontend/js/dashboard-domain.js index bba3709..a205bdf 100644 --- a/frontend/js/dashboard-domain.js +++ b/frontend/js/dashboard-domain.js @@ -36,9 +36,9 @@ // Creates a new domain. global.domainNewHandler = function() { var json = { - session: global.cookieGet("session"), - name: $("#new-domain-name").val(), - domain: $("#new-domain-domain").val(), + "ownerToken": global.cookieGet("ownerToken"), + "name": $("#new-domain-name").val(), + "domain": $("#new-domain-domain").val(), } global.buttonDisable("#add-site-button"); @@ -66,7 +66,7 @@ // Refreshes the list of domains. global.domainRefresh = function(callback) { var json = { - session: global.cookieGet("session"), + ownerToken: global.cookieGet("ownerToken"), }; global.post(global.commentoOrigin + "/api/domain/list", json, function(resp) { @@ -107,8 +107,8 @@ // Updates a domain with the backend. global.domainUpdate = function(domain, callback) { var json = { - session: global.cookieGet("session"), - domain: domain, + "ownerToken": global.cookieGet("ownerToken"), + "domain": domain, }; global.post(global.commentoOrigin + "/api/domain/update", json, function(resp) { @@ -126,8 +126,8 @@ // Deletes a domain. global.domainDelete = function(domain, callback) { var json = { - session: global.cookieGet("session"), - domain: domain, + "ownerToken": global.cookieGet("ownerToken"), + "domain": domain, }; global.post(global.commentoOrigin + "/api/domain/delete", json, function(resp) { diff --git a/frontend/js/dashboard-import.js b/frontend/js/dashboard-import.js index 2f8e4aa..132475d 100644 --- a/frontend/js/dashboard-import.js +++ b/frontend/js/dashboard-import.js @@ -12,9 +12,9 @@ var data = global.dashboard.$data; var json = { - session: global.cookieGet("session"), - domain: data.domains[data.cd].domain, - url: url, + "ownerToken": global.cookieGet("ownerToken"), + "domain": data.domains[data.cd].domain, + "url": url, } global.buttonDisable("#disqus-import-button"); diff --git a/frontend/js/dashboard-moderation.js b/frontend/js/dashboard-moderation.js index 598f68e..a23fb08 100644 --- a/frontend/js/dashboard-moderation.js +++ b/frontend/js/dashboard-moderation.js @@ -13,9 +13,9 @@ var email = $("#new-mod").val(); var json = { - session: global.cookieGet("session"), - domain: data.domains[data.cd].domain, - email: email, + "ownerToken": global.cookieGet("ownerToken"), + "domain": data.domains[data.cd].domain, + "email": email, } var idx = -1; @@ -53,9 +53,9 @@ var data = global.dashboard.$data; var json = { - session: global.cookieGet("session"), - domain: data.domains[data.cd].domain, - email: email, + "ownerToken": global.cookieGet("ownerToken"), + "domain": data.domains[data.cd].domain, + "email": email, } var idx = -1; diff --git a/frontend/js/dashboard-statistics.js b/frontend/js/dashboard-statistics.js index af99e6b..12d70a1 100644 --- a/frontend/js/dashboard-statistics.js +++ b/frontend/js/dashboard-statistics.js @@ -38,8 +38,8 @@ var data = global.dashboard.$data; var json = { - session: global.cookieGet("session"), - domain: data.domains[data.cd].domain, + "ownerToken": global.cookieGet("ownerToken"), + "domain": data.domains[data.cd].domain, } $(".view").hide(); diff --git a/frontend/js/login.js b/frontend/js/login.js index 3fdfd5c..8a49da4 100644 --- a/frontend/js/login.js +++ b/frontend/js/login.js @@ -65,7 +65,7 @@ return; } - global.cookieSet("session", resp.session); + global.cookieSet("ownerToken", resp.ownerToken); document.location = "/dashboard"; }); }; diff --git a/frontend/js/logout.js b/frontend/js/logout.js index b9da814..188dc90 100644 --- a/frontend/js/logout.js +++ b/frontend/js/logout.js @@ -1,7 +1,7 @@ (function (global, document) { global.logout = function() { - global.cookieSet("session", ""); + global.cookieSet("ownerToken", ""); document.location = "/login"; } diff --git a/frontend/js/self.js b/frontend/js/self.js index bd53f74..2bdd727 100644 --- a/frontend/js/self.js +++ b/frontend/js/self.js @@ -3,7 +3,7 @@ // Get self details. global.selfGet = function(callback) { var json = { - "session": global.cookieGet("session"), + "ownerToken": global.cookieGet("ownerToken"), }; global.post(global.commentoOrigin + "/api/owner/self", json, function(resp) {