Created
February 16, 2020 12:25
-
-
Save adxgun/da6378f8f4dc2cf807a4b31881f59396 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Option struct { | |
issuer, typ, name, account, service string | |
actions []string // requested actions | |
} | |
type Token struct { | |
Token string `json:"token"` | |
AccessToken string `json:"access_token"` | |
} | |
func (srv *tokenServer) createToken(opt *Option, actions []string) (*Token, error) { | |
// sign any string to get the used signing Algorithm for the private key | |
_, algo, err := srv.privateKey.Sign(strings.NewReader("AUTH"), 0) | |
if err != nil { | |
return nil, err | |
} | |
header := token.Header{ | |
Type: "JWT", | |
SigningAlg: algo, | |
KeyID: srv.pubKey.KeyID(), | |
} | |
headerJson, err := json.Marshal(header) | |
if err != nil { | |
return nil, err | |
} | |
now := time.Now().Unix() | |
exp := now + time.Now().Add(24*time.Hour).Unix() | |
claim := token.ClaimSet{ | |
Issuer: opt.issuer, | |
Subject: opt.account, | |
Audience: opt.service, | |
Expiration: exp, | |
NotBefore: now - 10, | |
IssuedAt: now, | |
JWTID: fmt.Sprintf("%d", rand.Int63()), | |
Access: []*token.ResourceActions{}, | |
} | |
claim.Access = append(claim.Access, &token.ResourceActions{ | |
Type: opt.typ, | |
Name: opt.name, | |
Actions: actions, | |
}) | |
claimJson, err := json.Marshal(claim) | |
if err != nil { | |
return nil, err | |
} | |
payload := fmt.Sprintf("%s%s%s", encodeBase64(headerJson), token.TokenSeparator, encodeBase64(claimJson)) | |
sig, sigAlgo, err := srv.privateKey.Sign(strings.NewReader(payload), 0) | |
if err != nil && sigAlgo != algo { | |
return nil, err | |
} | |
tk := fmt.Sprintf("%s%s%s", payload, token.TokenSeparator, encodeBase64(sig)) | |
return &Token{Token: tk, AccessToken: tk}, nil | |
} | |
func (srv *tokenServer) createTokenOption(r *http.Request) *Option { | |
opt := &Option{} | |
q := r.URL.Query() | |
opt.service = q.Get("service") | |
opt.account = q.Get("account") | |
opt.issuer = "Sample Issuer" // issuer value must match the value configured via docker-compose | |
parts := strings.Split(q.Get("scope"), ":") | |
if len(parts) > 0 { | |
opt.typ = parts[0] // repository | |
} | |
if len(parts) > 1 { | |
opt.name = parts[1] // foo/repoName | |
} | |
if len(parts) > 2 { | |
opt.actions = strings.Split(parts[2], ",") // requested actions | |
} | |
return opt | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment