forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
gitlab.go
135 lines (116 loc) · 3.58 KB
/
gitlab.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
package gitlab
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"path"
"github.com/RangelReale/osincli"
"github.com/golang/glog"
authapi "github.com/openshift/origin/pkg/oauthserver/api"
"github.com/openshift/origin/pkg/oauthserver/oauth/external"
)
const (
// Uses the GitLab User-API (http://doc.gitlab.com/ce/api/users.html#current-user)
// and OAuth-Provider (http://doc.gitlab.com/ce/integration/oauth_provider.html)
// with default OAuth scope (http://doc.gitlab.com/ce/api/users.html#current-user)
// Requires GitLab 7.7.0 or higher
gitlabAuthorizePath = "/oauth/authorize"
gitlabTokenPath = "/oauth/token"
gitlabUserAPIPath = "/api/v3/user"
gitlabOAuthScope = "api"
)
type provider struct {
providerName string
transport http.RoundTripper
authorizeURL string
tokenURL string
userAPIURL string
clientID string
clientSecret string
}
type gitlabUser struct {
ID uint64
Username string
Email string
Name string
}
func NewProvider(providerName string, transport http.RoundTripper, URL, clientID, clientSecret string) (external.Provider, error) {
// Create service URLs
u, err := url.Parse(URL)
if err != nil {
return nil, errors.New("Host URL is invalid")
}
return &provider{
providerName: providerName,
transport: transport,
authorizeURL: appendPath(*u, gitlabAuthorizePath),
tokenURL: appendPath(*u, gitlabTokenPath),
userAPIURL: appendPath(*u, gitlabUserAPIPath),
clientID: clientID,
clientSecret: clientSecret,
}, nil
}
func appendPath(u url.URL, subpath string) string {
u.Path = path.Join(u.Path, subpath)
return u.String()
}
func (p *provider) GetTransport() (http.RoundTripper, error) {
return p.transport, nil
}
// NewConfig implements external/interfaces/Provider.NewConfig
func (p *provider) NewConfig() (*osincli.ClientConfig, error) {
config := &osincli.ClientConfig{
ClientId: p.clientID,
ClientSecret: p.clientSecret,
ErrorsInStatusCode: true,
SendClientSecretInParams: true,
AuthorizeUrl: p.authorizeURL,
TokenUrl: p.tokenURL,
Scope: gitlabOAuthScope,
}
return config, nil
}
// AddCustomParameters implements external/interfaces/Provider.AddCustomParameters
func (p *provider) AddCustomParameters(req *osincli.AuthorizeRequest) {
}
// GetUserIdentity implements external/interfaces/Provider.GetUserIdentity
func (p *provider) GetUserIdentity(data *osincli.AccessData) (authapi.UserIdentityInfo, bool, error) {
req, _ := http.NewRequest("GET", p.userAPIURL, nil)
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", data.AccessToken))
client := http.DefaultClient
if p.transport != nil {
client = &http.Client{Transport: p.transport}
}
res, err := client.Do(req)
if err != nil {
return nil, false, err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, false, err
}
userdata := gitlabUser{}
err = json.Unmarshal(body, &userdata)
if err != nil {
return nil, false, err
}
if userdata.ID == 0 {
return nil, false, errors.New("Could not retrieve GitLab id")
}
identity := authapi.NewDefaultUserIdentityInfo(p.providerName, fmt.Sprintf("%d", userdata.ID))
if len(userdata.Name) > 0 {
identity.Extra[authapi.IdentityDisplayNameKey] = userdata.Name
}
if len(userdata.Username) > 0 {
identity.Extra[authapi.IdentityPreferredUsernameKey] = userdata.Username
}
if len(userdata.Email) > 0 {
identity.Extra[authapi.IdentityEmailKey] = userdata.Email
}
glog.V(4).Infof("Got identity=%#v", identity)
return identity, true, nil
}