github.com/whoyao/protocol@v0.0.0-20230519045905-2d8ace718ca5/auth/accesstoken.go (about)

     1  package auth
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/go-jose/go-jose/v3"
     7  	"github.com/go-jose/go-jose/v3/jwt"
     8  )
     9  
    10  const (
    11  	defaultValidDuration = 6 * time.Hour
    12  )
    13  
    14  // AccessToken produces token signed with API key and secret
    15  type AccessToken struct {
    16  	apiKey   string
    17  	secret   string
    18  	grant    ClaimGrants
    19  	validFor time.Duration
    20  }
    21  
    22  func NewAccessToken(key string, secret string) *AccessToken {
    23  	return &AccessToken{
    24  		apiKey: key,
    25  		secret: secret,
    26  	}
    27  }
    28  
    29  func (t *AccessToken) SetIdentity(identity string) *AccessToken {
    30  	t.grant.Identity = identity
    31  	return t
    32  }
    33  
    34  func (t *AccessToken) SetValidFor(duration time.Duration) *AccessToken {
    35  	t.validFor = duration
    36  	return t
    37  }
    38  
    39  func (t *AccessToken) SetName(name string) *AccessToken {
    40  	t.grant.Name = name
    41  	return t
    42  }
    43  
    44  func (t *AccessToken) AddGrant(grant *VideoGrant) *AccessToken {
    45  	t.grant.Video = grant
    46  	return t
    47  }
    48  
    49  func (t *AccessToken) SetMetadata(md string) *AccessToken {
    50  	t.grant.Metadata = md
    51  	return t
    52  }
    53  
    54  func (t *AccessToken) SetSha256(sha string) *AccessToken {
    55  	t.grant.Sha256 = sha
    56  	return t
    57  }
    58  
    59  func (t *AccessToken) ToJWT() (string, error) {
    60  	if t.apiKey == "" || t.secret == "" {
    61  		return "", ErrKeysMissing
    62  	}
    63  
    64  	sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: []byte(t.secret)},
    65  		(&jose.SignerOptions{}).WithType("JWT"))
    66  	if err != nil {
    67  		return "", err
    68  	}
    69  
    70  	validFor := defaultValidDuration
    71  	if t.validFor > 0 {
    72  		validFor = t.validFor
    73  	}
    74  
    75  	cl := jwt.Claims{
    76  		Issuer:    t.apiKey,
    77  		NotBefore: jwt.NewNumericDate(time.Now()),
    78  		Expiry:    jwt.NewNumericDate(time.Now().Add(validFor)),
    79  		Subject:   t.grant.Identity,
    80  	}
    81  	return jwt.Signed(sig).Claims(cl).Claims(&t.grant).CompactSerialize()
    82  }