Skip to content

Commit eda8bb1

Browse files
committed
Restrict access to just content relevant part of API
1 parent 9532368 commit eda8bb1

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

api/github.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package api
22

33
import (
4+
"errors"
45
"net/http"
56
"net/http/httputil"
67
"net/url"
78
"regexp"
9+
"strings"
810
)
911

1012
// GitHubGateway acts as a proxy to GitHub
@@ -15,6 +17,7 @@ type GitHubGateway struct {
1517
const defaultEndpoint = "https://api.github.com"
1618

1719
var pathRegexp = regexp.MustCompile("^/github/?")
20+
var allowedRegexp = regexp.MustCompile("^/github/(git|contents|pulls|branches)/")
1821

1922
func NewGitHubGateway() *GitHubGateway {
2023
return &GitHubGateway{
@@ -54,8 +57,8 @@ func (gh *GitHubGateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
5457
return
5558
}
5659

57-
if !gh.authenticate(w, r) {
58-
handleError(unauthorizedError("Not authorized to access this endpoint"), w, r)
60+
if err := gh.authenticate(w, r); err != nil {
61+
handleError(unauthorizedError(err.Error()), w, r)
5962
return
6063
}
6164

@@ -65,8 +68,14 @@ func (gh *GitHubGateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6568
} else {
6669
endpoint = defaultEndpoint
6770
}
71+
var apiURL string
72+
if strings.HasSuffix(endpoint, "/") {
73+
apiURL = endpoint + config.GitHub.Repo
74+
} else {
75+
apiURL = endpoint + "/" + config.GitHub.Repo
76+
}
6877

69-
target, err := url.Parse(endpoint)
78+
target, err := url.Parse(apiURL)
7079
if err != nil {
7180
handleError(internalServerError("Unable to process GitHub endpoint"), w, r)
7281
return
@@ -76,21 +85,17 @@ func (gh *GitHubGateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
7685
gh.proxy.ServeHTTP(w, r.WithContext(ctx))
7786
}
7887

79-
func (gh *GitHubGateway) authenticate(w http.ResponseWriter, r *http.Request) bool {
88+
func (gh *GitHubGateway) authenticate(w http.ResponseWriter, r *http.Request) error {
8089
ctx := r.Context()
8190
claims := getClaims(ctx)
8291
adminRoles := getRoles(ctx)
83-
config := getConfig(ctx)
8492

8593
if claims == nil {
86-
return false
94+
return errors.New("Access to endpoint not allowed: no claims found in Bearer token")
8795
}
8896

89-
if config.GitHub.Repo != "" {
90-
repoRegexp := regexp.MustCompile("^/github/repos/" + config.GitHub.Repo + "/?")
91-
if !repoRegexp.MatchString(r.URL.Path) {
92-
return false
93-
}
97+
if !allowedRegexp.MatchString(r.URL.Path) {
98+
return errors.New("Access to endpoint not allowed: this part of GitHub's API has been restricted")
9499
}
95100

96101
roles, ok := claims.AppMetaData["roles"]
@@ -100,11 +105,11 @@ func (gh *GitHubGateway) authenticate(w http.ResponseWriter, r *http.Request) bo
100105
role, _ := data.(string)
101106
for _, adminRole := range adminRoles {
102107
if role == adminRole.Name {
103-
return true
108+
return nil
104109
}
105110
}
106111
}
107112
}
108113

109-
return false
114+
return errors.New("Access to endpoint not allowed: your role doesn't allow access")
110115
}

0 commit comments

Comments
 (0)