From 34ca69424293490bff084eef95b1cf7e87073025 Mon Sep 17 00:00:00 2001 From: Gregory Eremin Date: Sun, 22 Mar 2015 20:25:18 +0700 Subject: [PATCH] Stat repo scoping Statistical queries are now scoped to repos that user have access to --- db/stat.go | 33 +++++++++++++++++++++++++-------- server/api.go | 8 ++++---- server/request.go | 9 ++++++++- server/server.go | 8 ++++---- server/stat.go | 16 ++++++++-------- 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/db/stat.go b/db/stat.go index c9974ed..21bb411 100644 --- a/db/stat.go +++ b/db/stat.go @@ -30,7 +30,7 @@ join users u on join repos r on c.repo_id = r.id` -func StatOrgTop(p map[string]interface{}) (res []StatItem) { +func StatOrgTop(login string, p map[string]interface{}) (res []StatItem) { defer measure(time.Now(), "StatOrgTop") mustSelectN(&res, fmt.Sprintf(` select @@ -41,6 +41,7 @@ func StatOrgTop(p map[string]interface{}) (res []StatItem) { `+joinContribFT+` where o.login = :org and + c.repo_id in `+reposScope(login)+` and c.week >= :from and c.week <= :to group by item @@ -49,7 +50,7 @@ func StatOrgTop(p map[string]interface{}) (res []StatItem) { return } -func StatOrgActivity(p map[string]interface{}) (res []StatPoint) { +func StatOrgActivity(login string, p map[string]interface{}) (res []StatPoint) { defer measure(time.Now(), "StatOrgActivity") mustSelectN(&res, fmt.Sprintf(` select @@ -61,6 +62,7 @@ func StatOrgActivity(p map[string]interface{}) (res []StatPoint) { `+joinContribFT+` where o.login = :org and + c.repo_id in `+reposScope(login)+` and c.week >= :from and c.week <= :to group by item, week @@ -69,7 +71,7 @@ func StatOrgActivity(p map[string]interface{}) (res []StatPoint) { return } -func StatTeamTop(p map[string]interface{}) (res []StatItem) { +func StatTeamTop(login string, p map[string]interface{}) (res []StatItem) { defer measure(time.Now(), "StatTeamTop") mustSelectN(&res, fmt.Sprintf(` select @@ -80,6 +82,7 @@ func StatTeamTop(p map[string]interface{}) (res []StatItem) { `+joinContribFT+` where o.login = :org and + c.repo_id in `+reposScope(login)+` and t.name = :team and c.week >= :from and c.week <= :to @@ -89,7 +92,7 @@ func StatTeamTop(p map[string]interface{}) (res []StatItem) { return } -func StatTeamActivity(p map[string]interface{}) (res []StatPoint) { +func StatTeamActivity(login string, p map[string]interface{}) (res []StatPoint) { defer measure(time.Now(), "StatTeamActivity") mustSelectN(&res, fmt.Sprintf(` select @@ -101,6 +104,7 @@ func StatTeamActivity(p map[string]interface{}) (res []StatPoint) { `+joinContribFT+` where o.login = :org and + c.repo_id in `+reposScope(login)+` and t.name = :team and c.week >= :from and c.week <= :to @@ -110,7 +114,7 @@ func StatTeamActivity(p map[string]interface{}) (res []StatPoint) { return } -func StatUserTop(p map[string]interface{}) (res []StatItem) { +func StatUserTop(login string, p map[string]interface{}) (res []StatItem) { defer measure(time.Now(), "StatUserTop") mustSelectN(&res, ` select @@ -126,6 +130,7 @@ func StatUserTop(p map[string]interface{}) (res []StatItem) { c.repo_id = r.id where o.login = :org and + c.repo_id in `+reposScope(login)+` and u.login = :user and c.week >= :from and c.week <= :to @@ -135,7 +140,7 @@ func StatUserTop(p map[string]interface{}) (res []StatItem) { return } -func StatUserActivity(p map[string]interface{}) (res []StatPoint) { +func StatUserActivity(login string, p map[string]interface{}) (res []StatPoint) { defer measure(time.Now(), "StatUserActivity") mustSelectN(&res, ` select @@ -152,6 +157,7 @@ func StatUserActivity(p map[string]interface{}) (res []StatPoint) { c.repo_id = r.id where o.login = :org and + c.repo_id in `+reposScope(login)+` and u.login = :user and c.week >= :from and c.week <= :to @@ -161,7 +167,7 @@ func StatUserActivity(p map[string]interface{}) (res []StatPoint) { return } -func StatRepoTop(p map[string]interface{}) (res []StatItem) { +func StatRepoTop(login string, p map[string]interface{}) (res []StatItem) { defer measure(time.Now(), "StatRepoTop") mustSelectN(&res, fmt.Sprintf(` select @@ -172,6 +178,7 @@ func StatRepoTop(p map[string]interface{}) (res []StatItem) { `+joinContribFT+` where o.login = :org and + c.repo_id in `+reposScope(login)+` and r.name = :repo and c.week >= :from and c.week <= :to @@ -181,7 +188,7 @@ func StatRepoTop(p map[string]interface{}) (res []StatItem) { return } -func StatRepoActivity(p map[string]interface{}) (res []StatPoint) { +func StatRepoActivity(login string, p map[string]interface{}) (res []StatPoint) { defer measure(time.Now(), "StatRepoActivity") mustSelectN(&res, fmt.Sprintf(` select @@ -193,6 +200,7 @@ func StatRepoActivity(p map[string]interface{}) (res []StatPoint) { `+joinContribFT+` where o.login = :org and + c.repo_id in `+reposScope(login)+` and r.name = :repo and c.week >= :from and c.week <= :to @@ -201,3 +209,12 @@ func StatRepoActivity(p map[string]interface{}) (res []StatPoint) { `, p["item"]), p) return } + +func reposScope(login string) string { + return fmt.Sprintf(`( + select repo_id + from team_repos tr + join team_members tm on tr.team_id = tm.team_id + join users u on u.login = %q + )`, login) +} diff --git a/server/api.go b/server/api.go index 01e4c1d..c584d07 100644 --- a/server/api.go +++ b/server/api.go @@ -6,25 +6,25 @@ import ( "github.com/localhots/empact/db" ) -func apiOrgsHandler(w http.ResponseWriter, r *http.Request) { +func apiUserOrgsHandler(w http.ResponseWriter, r *http.Request) { req, _ := parseRequest(w, r) orgs := db.UserOrgs(req.login) req.respondWith(orgs) } -func apiTeamsHandler(w http.ResponseWriter, r *http.Request) { +func apiOrgTeamsHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) teams := db.OrgTeams(stat.Org) req.respondWith(teams) } -func apiUsersHandler(w http.ResponseWriter, r *http.Request) { +func apiOrgUsersHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) users := db.OrgUsers(stat.Org) req.respondWith(users) } -func apiReposHandler(w http.ResponseWriter, r *http.Request) { +func apiOrgReposHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) repos := db.OrgRepos(stat.Org) req.respondWith(repos) diff --git a/server/request.go b/server/request.go index 4b94c3b..60f5a3f 100644 --- a/server/request.go +++ b/server/request.go @@ -41,7 +41,14 @@ func parseRequest(w http.ResponseWriter, r *http.Request) (*request, *statReques token: token, login: login, } - return req, parseStatRequest(r) + sr := parseStatRequest(r) + + // XXX: Hack for demo account + if req.login == "" { + req.login = "andrewarrow" + } + + return req, sr } func (r *request) authorize(token, login string) { diff --git a/server/server.go b/server/server.go index da1e142..3656e8c 100644 --- a/server/server.go +++ b/server/server.go @@ -22,10 +22,10 @@ func init() { http.HandleFunc("/auth/callback", authCallbackHandler) http.HandleFunc("/api/", authHandler) - http.HandleFunc("/api/orgs", apiOrgsHandler) - http.HandleFunc("/api/teams", apiTeamsHandler) - http.HandleFunc("/api/users", apiUsersHandler) - http.HandleFunc("/api/repos", apiReposHandler) + http.HandleFunc("/api/orgs", apiUserOrgsHandler) + http.HandleFunc("/api/teams", apiOrgTeamsHandler) + http.HandleFunc("/api/users", apiOrgUsersHandler) + http.HandleFunc("/api/repos", apiOrgReposHandler) http.HandleFunc("/api/weeks", apiOrgWeekRangeHandler) http.HandleFunc("/api/stat/orgs/top", statOrgTopHandler) diff --git a/server/stat.go b/server/stat.go index 580e95a..7d2a100 100644 --- a/server/stat.go +++ b/server/stat.go @@ -9,48 +9,48 @@ import ( func statOrgTopHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - top := db.StatOrgTop(structs.Map(stat)) + top := db.StatOrgTop(req.login, structs.Map(stat)) req.respondWith(top) } func statOrgActivityHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - activity := db.StatOrgActivity(structs.Map(stat)) + activity := db.StatOrgActivity(req.login, structs.Map(stat)) req.respondWith(activity) } func statTeamTopHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - top := db.StatTeamTop(structs.Map(stat)) + top := db.StatTeamTop(req.login, structs.Map(stat)) req.respondWith(top) } func statTeamActivityHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - activity := db.StatTeamActivity(structs.Map(stat)) + activity := db.StatTeamActivity(req.login, structs.Map(stat)) req.respondWith(activity) } func statUserTopHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - top := db.StatUserTop(structs.Map(stat)) + top := db.StatUserTop(req.login, structs.Map(stat)) req.respondWith(top) } func statUserActivityHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - activity := db.StatUserActivity(structs.Map(stat)) + activity := db.StatUserActivity(req.login, structs.Map(stat)) req.respondWith(activity) } func statRepoTopHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - top := db.StatRepoTop(structs.Map(stat)) + top := db.StatRepoTop(req.login, structs.Map(stat)) req.respondWith(top) } func statRepoActivityHandler(w http.ResponseWriter, r *http.Request) { req, stat := parseRequest(w, r) - activity := db.StatRepoActivity(structs.Map(stat)) + activity := db.StatRepoActivity(req.login, structs.Map(stat)) req.respondWith(activity) }