package tokenrequest import ( "fmt" "html/template" "io" "net/http" "path" "github.com/RangelReale/osincli" utilruntime "k8s.io/kubernetes/pkg/util/runtime" "github.com/openshift/origin/pkg/auth/server/login" ) const ( RequestTokenEndpoint = "/token/request" DisplayTokenEndpoint = "/token/display" ImplicitTokenEndpoint = "/token/implicit" ) type endpointDetails struct { publicMasterURL string originOAuthClient *osincli.Client } type Endpoints interface { Install(mux login.Mux, paths ...string) } func NewEndpoints(publicMasterURL string, originOAuthClient *osincli.Client) Endpoints { return &endpointDetails{publicMasterURL, originOAuthClient} } // Install registers the request token endpoints into a mux. It is expected that the // provided prefix will serve all operations func (endpoints *endpointDetails) Install(mux login.Mux, paths ...string) { for _, prefix := range paths { mux.HandleFunc(path.Join(prefix, RequestTokenEndpoint), endpoints.requestToken) mux.HandleFunc(path.Join(prefix, DisplayTokenEndpoint), endpoints.displayToken) mux.HandleFunc(path.Join(prefix, ImplicitTokenEndpoint), endpoints.implicitToken) } } // requestToken works for getting a token in your browser and seeing what your token is func (endpoints *endpointDetails) requestToken(w http.ResponseWriter, req *http.Request) { authReq := endpoints.originOAuthClient.NewAuthorizeRequest(osincli.CODE) oauthURL := authReq.GetAuthorizeUrlWithParams("") http.Redirect(w, req, oauthURL.String(), http.StatusFound) } func (endpoints *endpointDetails) displayToken(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/html; charset=UTF-8") data := tokenData{RequestURL: "request", PublicMasterURL: endpoints.publicMasterURL} authorizeReq := endpoints.originOAuthClient.NewAuthorizeRequest(osincli.CODE) authorizeData, err := authorizeReq.HandleRequest(req) if err != nil { data.Error = fmt.Sprintf("Error handling auth request: %v", err) w.WriteHeader(http.StatusInternalServerError) renderToken(w, data) return } accessReq := endpoints.originOAuthClient.NewAccessRequest(osincli.AUTHORIZATION_CODE, authorizeData) accessData, err := accessReq.GetToken() if err != nil { data.Error = fmt.Sprintf("Error getting token: %v", err) w.WriteHeader(http.StatusInternalServerError) renderToken(w, data) return } data.AccessToken = accessData.AccessToken renderToken(w, data) } func renderToken(w io.Writer, data tokenData) { if err := tokenTemplate.Execute(w, data); err != nil { utilruntime.HandleError(fmt.Errorf("unable to render token template: %v", err)) } } type tokenData struct { Error string AccessToken string RequestURL string PublicMasterURL string } // TODO: allow template to be read from an external file var tokenTemplate = template.Must(template.New("tokenTemplate").Parse(` {{ if .Error }} {{ .Error }} {{ else }}
{{.AccessToken}}
oc login --token={{.AccessToken}} --server={{.PublicMasterURL}}
curl -H "Authorization: Bearer {{.AccessToken}}" "{{.PublicMasterURL}}/oapi/v1/users/~"{{ end }}