forked from mystiq/dex
*: lots of renaming
This commit is contained in:
parent
f4c5722e42
commit
3110f45c3d
10 changed files with 81 additions and 81 deletions
|
@ -47,10 +47,10 @@ func (s *server) CreateClient(ctx context.Context, req *apipb.CreateClientReq) (
|
||||||
// and secrets which are restricted based on the storage.
|
// and secrets which are restricted based on the storage.
|
||||||
client := fromPBClient(req.Client)
|
client := fromPBClient(req.Client)
|
||||||
if client.ID == "" {
|
if client.ID == "" {
|
||||||
client.ID = storage.NewNonce()
|
client.ID = storage.NewID()
|
||||||
}
|
}
|
||||||
if client.Secret == "" {
|
if client.Secret == "" {
|
||||||
client.Secret = storage.NewNonce() + storage.NewNonce()
|
client.Secret = storage.NewID() + storage.NewID()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.storage.CreateClient(client); err != nil {
|
if err := s.storage.CreateClient(client); err != nil {
|
||||||
|
|
|
@ -224,7 +224,7 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) finalizeLogin(identity connector.Identity, authReqID, connectorID string, conn connector.Connector) (string, error) {
|
func (s *Server) finalizeLogin(identity connector.Identity, authReqID, connectorID string, conn connector.Connector) (string, error) {
|
||||||
claims := storage.Identity{
|
claims := storage.Claims{
|
||||||
UserID: identity.UserID,
|
UserID: identity.UserID,
|
||||||
Username: identity.Username,
|
Username: identity.Username,
|
||||||
Email: identity.Email,
|
Email: identity.Email,
|
||||||
|
@ -253,7 +253,7 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReqID, connector
|
||||||
}
|
}
|
||||||
|
|
||||||
updater := func(a storage.AuthRequest) (storage.AuthRequest, error) {
|
updater := func(a storage.AuthRequest) (storage.AuthRequest, error) {
|
||||||
a.Identity = &claims
|
a.Claims = &claims
|
||||||
a.ConnectorID = connectorID
|
a.ConnectorID = connectorID
|
||||||
a.ConnectorData = identity.ConnectorData
|
a.ConnectorData = identity.ConnectorData
|
||||||
return a, nil
|
return a, nil
|
||||||
|
@ -271,7 +271,7 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
||||||
s.renderError(w, http.StatusInternalServerError, errServerError, "")
|
s.renderError(w, http.StatusInternalServerError, errServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if authReq.Identity == nil {
|
if authReq.Claims == nil {
|
||||||
log.Printf("Auth request does not have an identity for approval")
|
log.Printf("Auth request does not have an identity for approval")
|
||||||
s.renderError(w, http.StatusInternalServerError, errServerError, "")
|
s.renderError(w, http.StatusInternalServerError, errServerError, "")
|
||||||
return
|
return
|
||||||
|
@ -280,7 +280,7 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "GET":
|
case "GET":
|
||||||
if s.skipApproval {
|
if s.skipApproval {
|
||||||
s.sendCodeResponse(w, r, authReq, *authReq.Identity)
|
s.sendCodeResponse(w, r, authReq)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
client, err := s.storage.GetClient(authReq.ClientID)
|
client, err := s.storage.GetClient(authReq.ClientID)
|
||||||
|
@ -289,17 +289,17 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
||||||
s.renderError(w, http.StatusInternalServerError, errServerError, "")
|
s.renderError(w, http.StatusInternalServerError, errServerError, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
renderApprovalTmpl(w, authReq.ID, *authReq.Identity, client, authReq.Scopes)
|
renderApprovalTmpl(w, authReq.ID, *authReq.Claims, client, authReq.Scopes)
|
||||||
case "POST":
|
case "POST":
|
||||||
if r.FormValue("approval") != "approve" {
|
if r.FormValue("approval") != "approve" {
|
||||||
s.renderError(w, http.StatusInternalServerError, "approval rejected", "")
|
s.renderError(w, http.StatusInternalServerError, "approval rejected", "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.sendCodeResponse(w, r, authReq, *authReq.Identity)
|
s.sendCodeResponse(w, r, authReq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authReq storage.AuthRequest, identity storage.Identity) {
|
func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authReq storage.AuthRequest) {
|
||||||
if authReq.Expiry.After(s.now()) {
|
if authReq.Expiry.After(s.now()) {
|
||||||
s.renderError(w, http.StatusBadRequest, errInvalidRequest, "Authorization request period has expired.")
|
s.renderError(w, http.StatusBadRequest, errInvalidRequest, "Authorization request period has expired.")
|
||||||
return
|
return
|
||||||
|
@ -315,12 +315,12 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := storage.AuthCode{
|
code := storage.AuthCode{
|
||||||
ID: storage.NewNonce(),
|
ID: storage.NewID(),
|
||||||
ClientID: authReq.ClientID,
|
ClientID: authReq.ClientID,
|
||||||
ConnectorID: authReq.ConnectorID,
|
ConnectorID: authReq.ConnectorID,
|
||||||
Nonce: authReq.Nonce,
|
Nonce: authReq.Nonce,
|
||||||
Scopes: authReq.Scopes,
|
Scopes: authReq.Scopes,
|
||||||
Identity: *authReq.Identity,
|
Claims: *authReq.Claims,
|
||||||
Expiry: s.now().Add(time.Minute * 5),
|
Expiry: s.now().Add(time.Minute * 5),
|
||||||
RedirectURI: authReq.RedirectURI,
|
RedirectURI: authReq.RedirectURI,
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,7 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
idToken, expiry, err := s.newIDToken(client.ID, authCode.Identity, authCode.Scopes, authCode.Nonce)
|
idToken, expiry, err := s.newIDToken(client.ID, authCode.Claims, authCode.Scopes, authCode.Nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to create ID token: %v", err)
|
log.Printf("failed to create ID token: %v", err)
|
||||||
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
||||||
|
@ -435,12 +435,12 @@ func (s *Server) handleAuthCode(w http.ResponseWriter, r *http.Request, client s
|
||||||
}()
|
}()
|
||||||
var refreshToken string
|
var refreshToken string
|
||||||
if reqRefresh {
|
if reqRefresh {
|
||||||
refresh := storage.Refresh{
|
refresh := storage.RefreshToken{
|
||||||
RefreshToken: storage.NewNonce(),
|
RefreshToken: storage.NewID(),
|
||||||
ClientID: authCode.ClientID,
|
ClientID: authCode.ClientID,
|
||||||
ConnectorID: authCode.ConnectorID,
|
ConnectorID: authCode.ConnectorID,
|
||||||
Scopes: authCode.Scopes,
|
Scopes: authCode.Scopes,
|
||||||
Identity: authCode.Identity,
|
Claims: authCode.Claims,
|
||||||
Nonce: authCode.Nonce,
|
Nonce: authCode.Nonce,
|
||||||
}
|
}
|
||||||
if err := s.storage.CreateRefresh(refresh); err != nil {
|
if err := s.storage.CreateRefresh(refresh); err != nil {
|
||||||
|
@ -497,7 +497,7 @@ func (s *Server) handleRefreshToken(w http.ResponseWriter, r *http.Request, clie
|
||||||
|
|
||||||
// TODO(ericchiang): re-auth with backends
|
// TODO(ericchiang): re-auth with backends
|
||||||
|
|
||||||
idToken, expiry, err := s.newIDToken(client.ID, refresh.Identity, scopes, refresh.Nonce)
|
idToken, expiry, err := s.newIDToken(client.ID, refresh.Claims, scopes, refresh.Nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to create ID token: %v", err)
|
log.Printf("failed to create ID token: %v", err)
|
||||||
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
||||||
|
@ -509,7 +509,7 @@ func (s *Server) handleRefreshToken(w http.ResponseWriter, r *http.Request, clie
|
||||||
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
refresh.RefreshToken = storage.NewNonce()
|
refresh.RefreshToken = storage.NewID()
|
||||||
if err := s.storage.CreateRefresh(refresh); err != nil {
|
if err := s.storage.CreateRefresh(refresh); err != nil {
|
||||||
log.Printf("failed to create refresh token: %v", err)
|
log.Printf("failed to create refresh token: %v", err)
|
||||||
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
tokenErr(w, errServerError, "", http.StatusInternalServerError)
|
||||||
|
@ -529,7 +529,7 @@ func (s *Server) writeAccessToken(w http.ResponseWriter, idToken, refreshToken s
|
||||||
RefreshToken string `json:"refresh_token,omitempty"`
|
RefreshToken string `json:"refresh_token,omitempty"`
|
||||||
IDToken string `json:"id_token"`
|
IDToken string `json:"id_token"`
|
||||||
}{
|
}{
|
||||||
storage.NewNonce(),
|
storage.NewID(),
|
||||||
"bearer",
|
"bearer",
|
||||||
int(expiry.Sub(s.now())),
|
int(expiry.Sub(s.now())),
|
||||||
refreshToken,
|
refreshToken,
|
||||||
|
|
|
@ -120,7 +120,7 @@ type idTokenClaims struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) newIDToken(clientID string, claims storage.Identity, scopes []string, nonce string) (idToken string, expiry time.Time, err error) {
|
func (s *Server) newIDToken(clientID string, claims storage.Claims, scopes []string, nonce string) (idToken string, expiry time.Time, err error) {
|
||||||
issuedAt := s.now()
|
issuedAt := s.now()
|
||||||
expiry = issuedAt.Add(s.idTokensValidFor)
|
expiry = issuedAt.Add(s.idTokensValidFor)
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ func parseAuthorizationRequest(s storage.Storage, r *http.Request) (req storage.
|
||||||
}
|
}
|
||||||
|
|
||||||
return storage.AuthRequest{
|
return storage.AuthRequest{
|
||||||
ID: storage.NewNonce(),
|
ID: storage.NewID(),
|
||||||
ClientID: client.ID,
|
ClientID: client.ID,
|
||||||
State: r.Form.Get("state"),
|
State: r.Form.Get("state"),
|
||||||
Nonce: r.Form.Get("nonce"),
|
Nonce: r.Form.Get("nonce"),
|
||||||
|
|
|
@ -72,7 +72,7 @@ var approvalTmpl = template.Must(template.New("approval-template").Parse(`<html>
|
||||||
</body>
|
</body>
|
||||||
</html>`))
|
</html>`))
|
||||||
|
|
||||||
func renderApprovalTmpl(w http.ResponseWriter, state string, identity storage.Identity, client storage.Client, scopes []string) {
|
func renderApprovalTmpl(w http.ResponseWriter, state string, identity storage.Claims, client storage.Client, scopes []string) {
|
||||||
data := struct {
|
data := struct {
|
||||||
User string
|
User string
|
||||||
ClientName string
|
ClientName string
|
||||||
|
|
|
@ -22,8 +22,8 @@ func TestGCAuthRequests(t *testing.T) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
cli.now = func() time.Time { return now }
|
cli.now = func() time.Time { return now }
|
||||||
|
|
||||||
expiredID := storage.NewNonce()
|
expiredID := storage.NewID()
|
||||||
goodID := storage.NewNonce()
|
goodID := storage.NewID()
|
||||||
|
|
||||||
must(cli.CreateAuthRequest(storage.AuthRequest{
|
must(cli.CreateAuthRequest(storage.AuthRequest{
|
||||||
ID: expiredID,
|
ID: expiredID,
|
||||||
|
@ -58,8 +58,8 @@ func TestGCAuthCodes(t *testing.T) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
cli.now = func() time.Time { return now }
|
cli.now = func() time.Time { return now }
|
||||||
|
|
||||||
expiredID := storage.NewNonce()
|
expiredID := storage.NewID()
|
||||||
goodID := storage.NewNonce()
|
goodID := storage.NewID()
|
||||||
|
|
||||||
must(cli.CreateAuthCode(storage.AuthCode{
|
must(cli.CreateAuthCode(storage.AuthCode{
|
||||||
ID: expiredID,
|
ID: expiredID,
|
||||||
|
|
|
@ -109,8 +109,8 @@ func (cli *client) CreateAuthCode(c storage.AuthCode) error {
|
||||||
return cli.post(resourceAuthCode, cli.fromStorageAuthCode(c))
|
return cli.post(resourceAuthCode, cli.fromStorageAuthCode(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *client) CreateRefresh(r storage.Refresh) error {
|
func (cli *client) CreateRefresh(r storage.RefreshToken) error {
|
||||||
refresh := Refresh{
|
refresh := RefreshToken{
|
||||||
TypeMeta: k8sapi.TypeMeta{
|
TypeMeta: k8sapi.TypeMeta{
|
||||||
Kind: kindRefreshToken,
|
Kind: kindRefreshToken,
|
||||||
APIVersion: cli.apiVersionForResource(resourceRefreshToken),
|
APIVersion: cli.apiVersionForResource(resourceRefreshToken),
|
||||||
|
@ -123,7 +123,7 @@ func (cli *client) CreateRefresh(r storage.Refresh) error {
|
||||||
ConnectorID: r.ConnectorID,
|
ConnectorID: r.ConnectorID,
|
||||||
Scopes: r.Scopes,
|
Scopes: r.Scopes,
|
||||||
Nonce: r.Nonce,
|
Nonce: r.Nonce,
|
||||||
Identity: fromStorageIdentity(r.Identity),
|
Claims: fromStorageClaims(r.Claims),
|
||||||
}
|
}
|
||||||
return cli.post(resourceRefreshToken, refresh)
|
return cli.post(resourceRefreshToken, refresh)
|
||||||
}
|
}
|
||||||
|
@ -160,18 +160,18 @@ func (cli *client) GetKeys() (storage.Keys, error) {
|
||||||
return toStorageKeys(keys), nil
|
return toStorageKeys(keys), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *client) GetRefresh(id string) (storage.Refresh, error) {
|
func (cli *client) GetRefresh(id string) (storage.RefreshToken, error) {
|
||||||
var r Refresh
|
var r RefreshToken
|
||||||
if err := cli.get(resourceRefreshToken, id, &r); err != nil {
|
if err := cli.get(resourceRefreshToken, id, &r); err != nil {
|
||||||
return storage.Refresh{}, err
|
return storage.RefreshToken{}, err
|
||||||
}
|
}
|
||||||
return storage.Refresh{
|
return storage.RefreshToken{
|
||||||
RefreshToken: r.ObjectMeta.Name,
|
RefreshToken: r.ObjectMeta.Name,
|
||||||
ClientID: r.ClientID,
|
ClientID: r.ClientID,
|
||||||
ConnectorID: r.ConnectorID,
|
ConnectorID: r.ConnectorID,
|
||||||
Scopes: r.Scopes,
|
Scopes: r.Scopes,
|
||||||
Nonce: r.Nonce,
|
Nonce: r.Nonce,
|
||||||
Identity: toStorageIdentity(r.Identity),
|
Claims: toStorageClaims(r.Claims),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ func (cli *client) ListClients() ([]storage.Client, error) {
|
||||||
return nil, errors.New("not implemented")
|
return nil, errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *client) ListRefreshTokens() ([]storage.Refresh, error) {
|
func (cli *client) ListRefreshTokens() ([]storage.RefreshToken, error) {
|
||||||
return nil, errors.New("not implemented")
|
return nil, errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ func toStorageClient(c Client) storage.Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identity is a mirrored struct from storage with JSON struct tags.
|
// Claims is a mirrored struct from storage with JSON struct tags.
|
||||||
type Identity struct {
|
type Claims struct {
|
||||||
UserID string `json:"userID"`
|
UserID string `json:"userID"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
|
@ -79,8 +79,8 @@ type Identity struct {
|
||||||
Groups []string `json:"groups,omitempty"`
|
Groups []string `json:"groups,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromStorageIdentity(i storage.Identity) Identity {
|
func fromStorageClaims(i storage.Claims) Claims {
|
||||||
return Identity{
|
return Claims{
|
||||||
UserID: i.UserID,
|
UserID: i.UserID,
|
||||||
Username: i.Username,
|
Username: i.Username,
|
||||||
Email: i.Email,
|
Email: i.Email,
|
||||||
|
@ -89,8 +89,8 @@ func fromStorageIdentity(i storage.Identity) Identity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toStorageIdentity(i Identity) storage.Identity {
|
func toStorageClaims(i Claims) storage.Claims {
|
||||||
return storage.Identity{
|
return storage.Claims{
|
||||||
UserID: i.UserID,
|
UserID: i.UserID,
|
||||||
Username: i.Username,
|
Username: i.Username,
|
||||||
Email: i.Email,
|
Email: i.Email,
|
||||||
|
@ -120,7 +120,7 @@ type AuthRequest struct {
|
||||||
|
|
||||||
// The identity of the end user. Generally nil until the user authenticates
|
// The identity of the end user. Generally nil until the user authenticates
|
||||||
// with a backend.
|
// with a backend.
|
||||||
Identity *Identity `json:"identity,omitempty"`
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
// The connector used to login the user. Set when the user authenticates.
|
// The connector used to login the user. Set when the user authenticates.
|
||||||
ConnectorID string `json:"connectorID,omitempty"`
|
ConnectorID string `json:"connectorID,omitempty"`
|
||||||
ConnectorData []byte `json:"connectorData,omitempty"`
|
ConnectorData []byte `json:"connectorData,omitempty"`
|
||||||
|
@ -149,9 +149,9 @@ func toStorageAuthRequest(req AuthRequest) storage.AuthRequest {
|
||||||
ConnectorData: req.ConnectorData,
|
ConnectorData: req.ConnectorData,
|
||||||
Expiry: req.Expiry,
|
Expiry: req.Expiry,
|
||||||
}
|
}
|
||||||
if req.Identity != nil {
|
if req.Claims != nil {
|
||||||
i := toStorageIdentity(*req.Identity)
|
i := toStorageClaims(*req.Claims)
|
||||||
a.Identity = &i
|
a.Claims = &i
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
@ -177,9 +177,9 @@ func (cli *client) fromStorageAuthRequest(a storage.AuthRequest) AuthRequest {
|
||||||
ConnectorData: a.ConnectorData,
|
ConnectorData: a.ConnectorData,
|
||||||
Expiry: a.Expiry,
|
Expiry: a.Expiry,
|
||||||
}
|
}
|
||||||
if a.Identity != nil {
|
if a.Claims != nil {
|
||||||
i := fromStorageIdentity(*a.Identity)
|
i := fromStorageClaims(*a.Claims)
|
||||||
req.Identity = &i
|
req.Claims = &i
|
||||||
}
|
}
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ type AuthCode struct {
|
||||||
Nonce string `json:"nonce,omitempty"`
|
Nonce string `json:"nonce,omitempty"`
|
||||||
State string `json:"state,omitempty"`
|
State string `json:"state,omitempty"`
|
||||||
|
|
||||||
Identity Identity `json:"identity,omitempty"`
|
Claims Claims `json:"claims,omitempty"`
|
||||||
|
|
||||||
ConnectorID string `json:"connectorID,omitempty"`
|
ConnectorID string `json:"connectorID,omitempty"`
|
||||||
ConnectorData []byte `json:"connectorData,omitempty"`
|
ConnectorData []byte `json:"connectorData,omitempty"`
|
||||||
|
@ -228,7 +228,7 @@ func (cli *client) fromStorageAuthCode(a storage.AuthCode) AuthCode {
|
||||||
ConnectorData: a.ConnectorData,
|
ConnectorData: a.ConnectorData,
|
||||||
Nonce: a.Nonce,
|
Nonce: a.Nonce,
|
||||||
Scopes: a.Scopes,
|
Scopes: a.Scopes,
|
||||||
Identity: fromStorageIdentity(a.Identity),
|
Claims: fromStorageClaims(a.Claims),
|
||||||
Expiry: a.Expiry,
|
Expiry: a.Expiry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,14 +242,14 @@ func toStorageAuthCode(a AuthCode) storage.AuthCode {
|
||||||
ConnectorData: a.ConnectorData,
|
ConnectorData: a.ConnectorData,
|
||||||
Nonce: a.Nonce,
|
Nonce: a.Nonce,
|
||||||
Scopes: a.Scopes,
|
Scopes: a.Scopes,
|
||||||
Identity: toStorageIdentity(a.Identity),
|
Claims: toStorageClaims(a.Claims),
|
||||||
Expiry: a.Expiry,
|
Expiry: a.Expiry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh is a mirrored struct from storage with JSON struct tags and
|
// RefreshToken is a mirrored struct from storage with JSON struct tags and
|
||||||
// Kubernetes type metadata.
|
// Kubernetes type metadata.
|
||||||
type Refresh struct {
|
type RefreshToken struct {
|
||||||
k8sapi.TypeMeta `json:",inline"`
|
k8sapi.TypeMeta `json:",inline"`
|
||||||
k8sapi.ObjectMeta `json:"metadata,omitempty"`
|
k8sapi.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
@ -258,15 +258,15 @@ type Refresh struct {
|
||||||
|
|
||||||
Nonce string `json:"nonce,omitempty"`
|
Nonce string `json:"nonce,omitempty"`
|
||||||
|
|
||||||
Identity Identity `json:"identity,omitempty"`
|
Claims Claims `json:"claims,omitempty"`
|
||||||
ConnectorID string `json:"connectorID,omitempty"`
|
ConnectorID string `json:"connectorID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshList is a list of refresh tokens.
|
// RefreshList is a list of refresh tokens.
|
||||||
type RefreshList struct {
|
type RefreshList struct {
|
||||||
k8sapi.TypeMeta `json:",inline"`
|
k8sapi.TypeMeta `json:",inline"`
|
||||||
k8sapi.ListMeta `json:"metadata,omitempty"`
|
k8sapi.ListMeta `json:"metadata,omitempty"`
|
||||||
RefreshTokens []Refresh `json:"items"`
|
RefreshTokens []RefreshToken `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys is a mirrored struct from storage with JSON struct tags and Kubernetes
|
// Keys is a mirrored struct from storage with JSON struct tags and Kubernetes
|
||||||
|
|
|
@ -13,7 +13,7 @@ func New() storage.Storage {
|
||||||
return &memStorage{
|
return &memStorage{
|
||||||
clients: make(map[string]storage.Client),
|
clients: make(map[string]storage.Client),
|
||||||
authCodes: make(map[string]storage.AuthCode),
|
authCodes: make(map[string]storage.AuthCode),
|
||||||
refreshTokens: make(map[string]storage.Refresh),
|
refreshTokens: make(map[string]storage.RefreshToken),
|
||||||
authReqs: make(map[string]storage.AuthRequest),
|
authReqs: make(map[string]storage.AuthRequest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ type memStorage struct {
|
||||||
|
|
||||||
clients map[string]storage.Client
|
clients map[string]storage.Client
|
||||||
authCodes map[string]storage.AuthCode
|
authCodes map[string]storage.AuthCode
|
||||||
refreshTokens map[string]storage.Refresh
|
refreshTokens map[string]storage.RefreshToken
|
||||||
authReqs map[string]storage.AuthRequest
|
authReqs map[string]storage.AuthRequest
|
||||||
|
|
||||||
keys storage.Keys
|
keys storage.Keys
|
||||||
|
@ -49,7 +49,7 @@ func (s *memStorage) CreateAuthCode(c storage.AuthCode) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *memStorage) CreateRefresh(r storage.Refresh) error {
|
func (s *memStorage) CreateRefresh(r storage.RefreshToken) error {
|
||||||
s.tx(func() { s.refreshTokens[r.RefreshToken] = r })
|
s.tx(func() { s.refreshTokens[r.RefreshToken] = r })
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func (s *memStorage) GetKeys() (keys storage.Keys, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *memStorage) GetRefresh(token string) (tok storage.Refresh, err error) {
|
func (s *memStorage) GetRefresh(token string) (tok storage.RefreshToken, err error) {
|
||||||
s.tx(func() {
|
s.tx(func() {
|
||||||
var ok bool
|
var ok bool
|
||||||
if tok, ok = s.refreshTokens[token]; !ok {
|
if tok, ok = s.refreshTokens[token]; !ok {
|
||||||
|
@ -105,7 +105,7 @@ func (s *memStorage) ListClients() (clients []storage.Client, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *memStorage) ListRefreshTokens() (tokens []storage.Refresh, err error) {
|
func (s *memStorage) ListRefreshTokens() (tokens []storage.RefreshToken, err error) {
|
||||||
s.tx(func() {
|
s.tx(func() {
|
||||||
for _, refresh := range s.refreshTokens {
|
for _, refresh := range s.refreshTokens {
|
||||||
tokens = append(tokens, refresh)
|
tokens = append(tokens, refresh)
|
||||||
|
@ -180,7 +180,7 @@ func (s *memStorage) ClaimCode(id string) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *memStorage) ClaimRefresh(refreshToken string) (token storage.Refresh, err error) {
|
func (s *memStorage) ClaimRefresh(refreshToken string) (token storage.RefreshToken, err error) {
|
||||||
s.tx(func() {
|
s.tx(func() {
|
||||||
var ok bool
|
var ok bool
|
||||||
if token, ok = s.refreshTokens[refreshToken]; !ok {
|
if token, ok = s.refreshTokens[refreshToken]; !ok {
|
||||||
|
|
|
@ -28,8 +28,8 @@ var ErrNotFound = errors.New("not found")
|
||||||
// TODO(ericchiang): refactor ID creation onto the storage.
|
// TODO(ericchiang): refactor ID creation onto the storage.
|
||||||
var encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
var encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||||
|
|
||||||
// NewNonce returns a new ID for the objects.
|
// NewID returns a random string which can be used as an ID for objects.
|
||||||
func NewNonce() string {
|
func NewID() string {
|
||||||
buff := make([]byte, 8) // 64 bit random ID.
|
buff := make([]byte, 8) // 64 bit random ID.
|
||||||
if _, err := io.ReadFull(rand.Reader, buff); err != nil {
|
if _, err := io.ReadFull(rand.Reader, buff); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -50,7 +50,7 @@ type Storage interface {
|
||||||
CreateAuthRequest(a AuthRequest) error
|
CreateAuthRequest(a AuthRequest) error
|
||||||
CreateClient(c Client) error
|
CreateClient(c Client) error
|
||||||
CreateAuthCode(c AuthCode) error
|
CreateAuthCode(c AuthCode) error
|
||||||
CreateRefresh(r Refresh) error
|
CreateRefresh(r RefreshToken) error
|
||||||
|
|
||||||
// TODO(ericchiang): return (T, bool, error) so we can indicate not found
|
// TODO(ericchiang): return (T, bool, error) so we can indicate not found
|
||||||
// requests that way instead of using ErrNotFound.
|
// requests that way instead of using ErrNotFound.
|
||||||
|
@ -58,10 +58,10 @@ type Storage interface {
|
||||||
GetAuthCode(id string) (AuthCode, error)
|
GetAuthCode(id string) (AuthCode, error)
|
||||||
GetClient(id string) (Client, error)
|
GetClient(id string) (Client, error)
|
||||||
GetKeys() (Keys, error)
|
GetKeys() (Keys, error)
|
||||||
GetRefresh(id string) (Refresh, error)
|
GetRefresh(id string) (RefreshToken, error)
|
||||||
|
|
||||||
ListClients() ([]Client, error)
|
ListClients() ([]Client, error)
|
||||||
ListRefreshTokens() ([]Refresh, error)
|
ListRefreshTokens() ([]RefreshToken, error)
|
||||||
|
|
||||||
// Delete methods MUST be atomic.
|
// Delete methods MUST be atomic.
|
||||||
DeleteAuthRequest(id string) error
|
DeleteAuthRequest(id string) error
|
||||||
|
@ -96,8 +96,8 @@ type Client struct {
|
||||||
LogoURL string
|
LogoURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identity represents the ID Token claims supported by the server.
|
// Claims represents the ID Token claims supported by the server.
|
||||||
type Identity struct {
|
type Claims struct {
|
||||||
UserID string
|
UserID string
|
||||||
Username string
|
Username string
|
||||||
Email string
|
Email string
|
||||||
|
@ -126,7 +126,7 @@ type AuthRequest struct {
|
||||||
|
|
||||||
// The identity of the end user. Generally nil until the user authenticates
|
// The identity of the end user. Generally nil until the user authenticates
|
||||||
// with a backend.
|
// with a backend.
|
||||||
Identity *Identity
|
Claims *Claims
|
||||||
|
|
||||||
// The connector used to login the user and any data the connector wishes to persists.
|
// The connector used to login the user and any data the connector wishes to persists.
|
||||||
// Set when the user authenticates.
|
// Set when the user authenticates.
|
||||||
|
@ -150,13 +150,13 @@ type AuthCode struct {
|
||||||
|
|
||||||
Scopes []string
|
Scopes []string
|
||||||
|
|
||||||
Identity Identity
|
Claims Claims
|
||||||
|
|
||||||
Expiry time.Time
|
Expiry time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh is an OAuth2 refresh token.
|
// RefreshToken is an OAuth2 refresh token.
|
||||||
type Refresh struct {
|
type RefreshToken struct {
|
||||||
// The actual refresh token.
|
// The actual refresh token.
|
||||||
RefreshToken string
|
RefreshToken string
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ type Refresh struct {
|
||||||
|
|
||||||
Nonce string
|
Nonce string
|
||||||
|
|
||||||
Identity Identity
|
Claims Claims
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerificationKey is a rotated signing key which can still be used to verify
|
// VerificationKey is a rotated signing key which can still be used to verify
|
||||||
|
|
|
@ -21,7 +21,7 @@ func RunTestSuite(t *testing.T, s storage.Storage) {
|
||||||
|
|
||||||
func testUpdateAuthRequest(t *testing.T, s storage.Storage) {
|
func testUpdateAuthRequest(t *testing.T, s storage.Storage) {
|
||||||
a := storage.AuthRequest{
|
a := storage.AuthRequest{
|
||||||
ID: storage.NewNonce(),
|
ID: storage.NewID(),
|
||||||
ClientID: "foobar",
|
ClientID: "foobar",
|
||||||
ResponseTypes: []string{"code"},
|
ResponseTypes: []string{"code"},
|
||||||
Scopes: []string{"openid", "email"},
|
Scopes: []string{"openid", "email"},
|
||||||
|
@ -29,13 +29,13 @@ func testUpdateAuthRequest(t *testing.T, s storage.Storage) {
|
||||||
Expiry: neverExpire,
|
Expiry: neverExpire,
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := storage.Identity{Email: "foobar"}
|
identity := storage.Claims{Email: "foobar"}
|
||||||
|
|
||||||
if err := s.CreateAuthRequest(a); err != nil {
|
if err := s.CreateAuthRequest(a); err != nil {
|
||||||
t.Fatalf("failed creating auth request: %v", err)
|
t.Fatalf("failed creating auth request: %v", err)
|
||||||
}
|
}
|
||||||
if err := s.UpdateAuthRequest(a.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) {
|
if err := s.UpdateAuthRequest(a.ID, func(old storage.AuthRequest) (storage.AuthRequest, error) {
|
||||||
old.Identity = &identity
|
old.Claims = &identity
|
||||||
old.ConnectorID = "connID"
|
old.ConnectorID = "connID"
|
||||||
return old, nil
|
return old, nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -46,17 +46,17 @@ func testUpdateAuthRequest(t *testing.T, s storage.Storage) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to get auth req: %v", err)
|
t.Fatalf("failed to get auth req: %v", err)
|
||||||
}
|
}
|
||||||
if got.Identity == nil {
|
if got.Claims == nil {
|
||||||
t.Fatalf("no identity in auth request")
|
t.Fatalf("no identity in auth request")
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(*got.Identity, identity) {
|
if !reflect.DeepEqual(*got.Claims, identity) {
|
||||||
t.Fatalf("update failed, wanted identity=%#v got %#v", identity, *got.Identity)
|
t.Fatalf("update failed, wanted identity=%#v got %#v", identity, *got.Claims)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateRefresh(t *testing.T, s storage.Storage) {
|
func testCreateRefresh(t *testing.T, s storage.Storage) {
|
||||||
id := storage.NewNonce()
|
id := storage.NewID()
|
||||||
refresh := storage.Refresh{
|
refresh := storage.RefreshToken{
|
||||||
RefreshToken: id,
|
RefreshToken: id,
|
||||||
ClientID: "client_id",
|
ClientID: "client_id",
|
||||||
ConnectorID: "client_secret",
|
ConnectorID: "client_secret",
|
||||||
|
|
Loading…
Reference in a new issue