mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-17 11:07:18 +02:00
directory: additional user info (#1467)
* directory: support additional user information * implement github * implement gitlab * implement onelogin * implement okta * rename to display name * implement google * fill in properties * fix azure email parsing * fix tests, lint * fix onelogin tests * fix gitlab/github tests
This commit is contained in:
parent
88580cf2fb
commit
3e86d2f9bf
13 changed files with 339 additions and 165 deletions
|
@ -2,12 +2,10 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
|
@ -121,9 +119,16 @@ func (p *Provider) UserGroups(ctx context.Context) ([]*directory.Group, []*direc
|
|||
|
||||
var users []*directory.User
|
||||
for userLogin, groups := range userLoginToGroups {
|
||||
u, err := p.getUser(ctx, userLogin)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
user := &directory.User{
|
||||
Id: databroker.GetUserID(Name, userLogin),
|
||||
GroupIds: groups,
|
||||
Id: databroker.GetUserID(Name, userLogin),
|
||||
GroupIds: groups,
|
||||
DisplayName: u.Name,
|
||||
Email: u.Email,
|
||||
}
|
||||
sort.Strings(user.GroupIds)
|
||||
users = append(users, user)
|
||||
|
@ -143,7 +148,7 @@ func (p *Provider) listOrgs(ctx context.Context) (orgSlugs []string, err error)
|
|||
var results []struct {
|
||||
Login string `json:"login"`
|
||||
}
|
||||
hdrs, err := p.api(ctx, "GET", nextURL, nil, &results)
|
||||
hdrs, err := p.api(ctx, nextURL, &results)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -169,7 +174,7 @@ func (p *Provider) listGroups(ctx context.Context, orgSlug string) ([]*directory
|
|||
ID int `json:"id"`
|
||||
Slug string `json:"slug"`
|
||||
}
|
||||
hdrs, err := p.api(ctx, "GET", nextURL, nil, &results)
|
||||
hdrs, err := p.api(ctx, nextURL, &results)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -196,7 +201,7 @@ func (p *Provider) listTeamMembers(ctx context.Context, orgSlug, teamSlug string
|
|||
var results []struct {
|
||||
Login string `json:"login"`
|
||||
}
|
||||
hdrs, err := p.api(ctx, "GET", nextURL, nil, &results)
|
||||
hdrs, err := p.api(ctx, nextURL, &results)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -211,16 +216,22 @@ func (p *Provider) listTeamMembers(ctx context.Context, orgSlug, teamSlug string
|
|||
return userLogins, err
|
||||
}
|
||||
|
||||
func (p *Provider) api(ctx context.Context, method string, apiURL string, in, out interface{}) (http.Header, error) {
|
||||
var body io.Reader
|
||||
if in != nil {
|
||||
bs, err := json.Marshal(in)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("github: failed to marshal api input")
|
||||
}
|
||||
body = bytes.NewReader(bs)
|
||||
func (p *Provider) getUser(ctx context.Context, userLogin string) (*apiUserObject, error) {
|
||||
apiURL := p.cfg.url.ResolveReference(&url.URL{
|
||||
Path: fmt.Sprintf("/users/%s", userLogin),
|
||||
}).String()
|
||||
|
||||
var res apiUserObject
|
||||
_, err := p.api(ctx, apiURL, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, method, apiURL, body)
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (p *Provider) api(ctx context.Context, apiURL string, out interface{}) (http.Header, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", apiURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("github: failed to create http request: %w", err)
|
||||
}
|
||||
|
@ -283,3 +294,10 @@ func ParseServiceAccount(rawServiceAccount string) (*ServiceAccount, error) {
|
|||
|
||||
return &serviceAccount, nil
|
||||
}
|
||||
|
||||
// see: https://docs.github.com/en/free-pro-team@latest/rest/reference/users#get-a-user
|
||||
type apiUserObject struct {
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
|
|
@ -75,6 +75,16 @@ func newMockAPI(t *testing.T, srv *httptest.Server) http.Handler {
|
|||
teamID := chi.URLParam(r, "team_id")
|
||||
json.NewEncoder(w).Encode(members[orgID][teamID])
|
||||
})
|
||||
r.Get("/users/{user_id}", func(w http.ResponseWriter, r *http.Request) {
|
||||
users := map[string]apiUserObject{
|
||||
"user1": {Login: "user1", Name: "User 1", Email: "user1@example.com"},
|
||||
"user2": {Login: "user2", Name: "User 2", Email: "user2@example.com"},
|
||||
"user3": {Login: "user3", Name: "User 3", Email: "user3@example.com"},
|
||||
"user4": {Login: "user4", Name: "User 4", Email: "user4@example.com"},
|
||||
}
|
||||
userID := chi.URLParam(r, "user_id")
|
||||
json.NewEncoder(w).Encode(users[userID])
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -96,10 +106,10 @@ func Test(t *testing.T) {
|
|||
groups, users, err := p.UserGroups(context.Background())
|
||||
assert.NoError(t, err)
|
||||
testutil.AssertProtoJSONEqual(t, `[
|
||||
{ "id": "github/user1", "groupIds": ["1", "2", "3"] },
|
||||
{ "id": "github/user2", "groupIds": ["1", "3"] },
|
||||
{ "id": "github/user3", "groupIds": ["3"] },
|
||||
{ "id": "github/user4", "groupIds": ["4"] }
|
||||
{ "id": "github/user1", "groupIds": ["1", "2", "3"], "displayName": "User 1", "email": "user1@example.com" },
|
||||
{ "id": "github/user2", "groupIds": ["1", "3"], "displayName": "User 2", "email": "user2@example.com" },
|
||||
{ "id": "github/user3", "groupIds": ["3"], "displayName": "User 3", "email": "user3@example.com" },
|
||||
{ "id": "github/user4", "groupIds": ["4"], "displayName": "User 4", "email": "user4@example.com" }
|
||||
]`, users)
|
||||
testutil.AssertProtoJSONEqual(t, `[
|
||||
{ "id": "1", "name": "team1" },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue