Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/auth/api/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package api

// TODO: Add display name to common meta?
type UserInfo interface {
GetName() string
GetUID() string
Expand Down
2 changes: 2 additions & 0 deletions pkg/auth/authenticator/file/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

type TokenAuthenticator struct {
path string
tokens map[string]*api.DefaultUserInfo
}

Expand Down Expand Up @@ -43,6 +44,7 @@ func NewTokenAuthenticator(path string) (*TokenAuthenticator, error) {
}

return &TokenAuthenticator{
path: file.Name(),
tokens: tokens,
}, nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/auth/handlers/authrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package handlers
import (
"net/http"

"github.com/golang/glog"
"github.com/openshift/origin/pkg/auth/authenticator"
)

Expand All @@ -17,6 +18,9 @@ func NewRequestAuthenticator(context RequestContext, auth authenticator.Request,
if err != nil || !ok {
failed.ServeHTTP(w, req)
return
} else {
glog.V(1).Infof("Found user, %v, when accessing %v", user, req.URL)

}

context.Set(req, user)
Expand Down
86 changes: 86 additions & 0 deletions pkg/auth/oauth/external/github/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package github

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"

"github.com/RangelReale/osincli"
"github.com/openshift/origin/pkg/auth/api"
"github.com/openshift/origin/pkg/auth/oauth/external"
)

const (
githubAuthorizeUrl = "https://github.com/login/oauth/authorize"
githubTokenUrl = "https://github.com/login/oauth/access_token"
githubUserApiUrl = "https://api.github.com/user"
githubOauthScope = "user:email"
)

type provider struct {
client_id, client_secret string
}

type githubUser struct {
ID uint64
Login string
Email string
Name string
}

func NewProvider(client_id, client_secret string) external.Provider {
return provider{client_id, client_secret}
}

func (p provider) NewConfig() (*osincli.ClientConfig, error) {
config := &osincli.ClientConfig{
ClientId: p.client_id,
ClientSecret: p.client_secret,
ErrorsInStatusCode: true,
SendClientSecretInParams: true,
AuthorizeUrl: githubAuthorizeUrl,
TokenUrl: githubTokenUrl,
Scope: githubOauthScope,
}
return config, nil
}

func (p provider) AddCustomParameters(req *osincli.AuthorizeRequest) {
}

func (p provider) GetUserInfo(data *osincli.AccessData) (api.UserInfo, bool, error) {

req, _ := http.NewRequest("GET", githubUserApiUrl, nil)
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", data.AccessToken))

res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, false, err
}

body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, false, err
}

userdata := githubUser{}
err = json.Unmarshal(body, &userdata)
if err != nil {
return nil, false, err
}

if userdata.ID == 0 {
return nil, false, fmt.Errorf("Could not retrieve GitHub id")
}

user := &api.DefaultUserInfo{
Name: fmt.Sprintf("%d", userdata.ID),
Extra: map[string]string{
"name": userdata.Name,
"login": userdata.Login,
"email": userdata.Email,
},
}
return user, true, nil
}
106 changes: 106 additions & 0 deletions pkg/auth/oauth/external/google/google.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package google

import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"

"github.com/RangelReale/osincli"
"github.com/golang/glog"
"github.com/openshift/origin/pkg/auth/api"
"github.com/openshift/origin/pkg/auth/oauth/external"
)

const (
googleAuthorizeUrl = "https://accounts.google.com/o/oauth2/auth"
googleTokenUrl = "https://accounts.google.com/o/oauth2/token"
googleOauthScope = "profile email"
)

type provider struct {
client_id, client_secret string
}

func NewProvider(client_id, client_secret string) external.Provider {
return provider{client_id, client_secret}
}

func (p provider) NewConfig() (*osincli.ClientConfig, error) {
config := &osincli.ClientConfig{
ClientId: p.client_id,
ClientSecret: p.client_secret,
ErrorsInStatusCode: true,
SendClientSecretInParams: true,
AuthorizeUrl: googleAuthorizeUrl,
TokenUrl: googleTokenUrl,
Scope: googleOauthScope,
}
return config, nil
}

func (p provider) AddCustomParameters(req *osincli.AuthorizeRequest) {
req.CustomParameters["include_granted_scopes"] = "true"
req.CustomParameters["access_type"] = "offline"
}

func (p provider) GetUserInfo(data *osincli.AccessData) (api.UserInfo, bool, error) {
idToken, ok := data.ResponseData["id_token"].(string)
if !ok {
return nil, false, fmt.Errorf("No id_token returned in %v", data.ResponseData)
}

userdata, err := decodeJWT(idToken)
if err != nil {
return nil, false, err
}

id, _ := userdata["id"].(string)
email, _ := userdata["email"].(string)
if id == "" || email == "" {
return nil, false, fmt.Errorf("Could not retrieve Google id")
}

user := &api.DefaultUserInfo{
Name: id,
Extra: map[string]string{
"name": email,
"email": email,
},
}
return user, true, nil
}

// Decode JWT
// http://openid.net/specs/draft-jones-json-web-token-07.html
func decodeJWT(jwt string) (map[string]interface{}, error) {
jwtParts := strings.Split(jwt, ".")
if len(jwtParts) != 3 {
return nil, fmt.Errorf("Invalid JSON Web Token: expected 3 parts, got %d", len(jwtParts))
}

encodedPayload := jwtParts[1]
glog.V(4).Infof("got encodedPayload")

// Re-pad, if needed
if l := len(encodedPayload) % 4; l != 0 {
padding := strings.Repeat("=", 4-l)
encodedPayload += padding
glog.V(4).Infof("added padding: %s\n", padding)
}

decodedPayload, err := base64.StdEncoding.DecodeString(encodedPayload)
if err != nil {
return nil, fmt.Errorf("Error decoding payload: %v\n", err)
}
glog.V(4).Infof("got decodedPayload")

var data map[string]interface{}
err = json.Unmarshal([]byte(decodedPayload), &data)
if err != nil {
return nil, fmt.Errorf("Error parsing token: %v\n", err)
}
glog.V(4).Infof("got id_token data")

return data, nil
}
Loading