Skip to content

Instantly share code, notes, and snippets.

@adigunhammedolalekan
Created February 16, 2020 12:25
Show Gist options
  • Save adigunhammedolalekan/da6378f8f4dc2cf807a4b31881f59396 to your computer and use it in GitHub Desktop.
Save adigunhammedolalekan/da6378f8f4dc2cf807a4b31881f59396 to your computer and use it in GitHub Desktop.
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