1
1
package api
2
2
3
3
import (
4
+ "errors"
4
5
"net/http"
5
6
"net/http/httputil"
6
7
"net/url"
7
8
"regexp"
9
+ "strings"
8
10
)
9
11
10
12
// GitHubGateway acts as a proxy to GitHub
@@ -15,6 +17,7 @@ type GitHubGateway struct {
15
17
const defaultEndpoint = "https://api.github.com"
16
18
17
19
var pathRegexp = regexp .MustCompile ("^/github/?" )
20
+ var allowedRegexp = regexp .MustCompile ("^/github/(git|contents|pulls|branches)/" )
18
21
19
22
func NewGitHubGateway () * GitHubGateway {
20
23
return & GitHubGateway {
@@ -54,8 +57,8 @@ func (gh *GitHubGateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
54
57
return
55
58
}
56
59
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 )
59
62
return
60
63
}
61
64
@@ -65,8 +68,14 @@ func (gh *GitHubGateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
65
68
} else {
66
69
endpoint = defaultEndpoint
67
70
}
71
+ var apiURL string
72
+ if strings .HasSuffix (endpoint , "/" ) {
73
+ apiURL = endpoint + config .GitHub .Repo
74
+ } else {
75
+ apiURL = endpoint + "/" + config .GitHub .Repo
76
+ }
68
77
69
- target , err := url .Parse (endpoint )
78
+ target , err := url .Parse (apiURL )
70
79
if err != nil {
71
80
handleError (internalServerError ("Unable to process GitHub endpoint" ), w , r )
72
81
return
@@ -76,21 +85,17 @@ func (gh *GitHubGateway) ServeHTTP(w http.ResponseWriter, r *http.Request) {
76
85
gh .proxy .ServeHTTP (w , r .WithContext (ctx ))
77
86
}
78
87
79
- func (gh * GitHubGateway ) authenticate (w http.ResponseWriter , r * http.Request ) bool {
88
+ func (gh * GitHubGateway ) authenticate (w http.ResponseWriter , r * http.Request ) error {
80
89
ctx := r .Context ()
81
90
claims := getClaims (ctx )
82
91
adminRoles := getRoles (ctx )
83
- config := getConfig (ctx )
84
92
85
93
if claims == nil {
86
- return false
94
+ return errors . New ( "Access to endpoint not allowed: no claims found in Bearer token" )
87
95
}
88
96
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" )
94
99
}
95
100
96
101
roles , ok := claims .AppMetaData ["roles" ]
@@ -100,11 +105,11 @@ func (gh *GitHubGateway) authenticate(w http.ResponseWriter, r *http.Request) bo
100
105
role , _ := data .(string )
101
106
for _ , adminRole := range adminRoles {
102
107
if role == adminRole .Name {
103
- return true
108
+ return nil
104
109
}
105
110
}
106
111
}
107
112
}
108
113
109
- return false
114
+ return errors . New ( "Access to endpoint not allowed: your role doesn't allow access" )
110
115
}
0 commit comments