-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathaccess.go
187 lines (147 loc) · 4.96 KB
/
access.go
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// SPDX-License-Identifier: Apache-2.0
package github
import (
"context"
"strings"
"github.com/sirupsen/logrus"
"github.com/go-vela/types/library"
"github.com/google/go-github/v56/github"
)
// OrgAccess captures the user's access level for an org.
func (c *client) OrgAccess(ctx context.Context, u *library.User, org string) (string, error) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"user": u.GetName(),
}).Tracef("capturing %s access level to org %s", u.GetName(), org)
// check if user is accessing personal org
if strings.EqualFold(org, u.GetName()) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"user": u.GetName(),
}).Debugf("skipping access level check for user %s with org %s", u.GetName(), org)
//nolint:goconst // ignore making constant
return "admin", nil
}
// create GitHub OAuth client with user's token
client := c.newClientToken(*u.Token)
// send API call to capture org access level for user
membership, _, err := client.Organizations.GetOrgMembership(ctx, *u.Name, org)
if err != nil {
return "", err
}
// return their access level if they are an active user
if membership.GetState() == "active" {
return membership.GetRole(), nil
}
return "", nil
}
// RepoAccess captures the user's access level for a repo.
func (c *client) RepoAccess(ctx context.Context, name, token, org, repo string) (string, error) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"repo": repo,
"user": name,
}).Tracef("capturing %s access level to repo %s/%s", name, org, repo)
// check if user is accessing repo in personal org
if strings.EqualFold(org, name) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"repo": repo,
"user": name,
}).Debugf("skipping access level check for user %s with repo %s/%s", name, org, repo)
return "admin", nil
}
// create github oauth client with the given token
//
//nolint:contextcheck // ignore context passing
client := c.newClientToken(token)
// send API call to capture repo access level for user
perm, _, err := client.Repositories.GetPermissionLevel(ctx, org, repo, name)
if err != nil {
return "", err
}
return perm.GetPermission(), nil
}
// TeamAccess captures the user's access level for a team.
func (c *client) TeamAccess(ctx context.Context, u *library.User, org, team string) (string, error) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"team": team,
"user": u.GetName(),
}).Tracef("capturing %s access level to team %s/%s", u.GetName(), org, team)
// check if user is accessing team in personal org
if strings.EqualFold(org, u.GetName()) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"team": team,
"user": u.GetName(),
}).Debugf("skipping access level check for user %s with team %s/%s", u.GetName(), org, team)
return "admin", nil
}
// create GitHub OAuth client with user's token
client := c.newClientToken(u.GetToken())
teams := []*github.Team{}
// set the max per page for the options to capture the list of repos
opts := github.ListOptions{PerPage: 100} // 100 is max
for {
// send API call to list all teams for the user
uTeams, resp, err := client.Teams.ListUserTeams(ctx, &opts)
if err != nil {
return "", err
}
teams = append(teams, uTeams...)
// break the loop if there is no more results to page through
if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}
// iterate through each element in the teams
for _, t := range teams {
// skip the team if does not match the team we are checking
if !strings.EqualFold(team, t.GetName()) {
continue
}
// skip the org if does not match the org we are checking
if !strings.EqualFold(org, t.GetOrganization().GetLogin()) {
continue
}
// return admin access if the user is a part of that team
return "admin", nil
}
return "", nil
}
// ListUsersTeamsForOrg captures the user's teams for an org.
func (c *client) ListUsersTeamsForOrg(ctx context.Context, u *library.User, org string) ([]string, error) {
c.Logger.WithFields(logrus.Fields{
"org": org,
"user": u.GetName(),
}).Tracef("capturing %s team membership for org %s", u.GetName(), org)
// create GitHub OAuth client with user's token
client := c.newClientToken(u.GetToken())
teams := []*github.Team{}
// set the max per page for the options to capture the list of repos
opts := github.ListOptions{PerPage: 100} // 100 is max
for {
// send API call to list all teams for the user
uTeams, resp, err := client.Teams.ListUserTeams(ctx, &opts)
if err != nil {
return []string{""}, err
}
teams = append(teams, uTeams...)
// break the loop if there is no more results to page through
if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}
var userTeams []string
// iterate through each element in the teams and filter teams for specified org
for _, t := range teams {
// skip the org if does not match the org we are checking
if strings.EqualFold(org, t.GetOrganization().GetLogin()) {
userTeams = append(userTeams, t.GetName())
}
}
return userTeams, nil
}