github.com/livekit/protocol@v1.39.3/auth/accesstoken.go (about)

     1  // Copyright 2023 LiveKit, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package auth
    16  
    17  import (
    18  	"time"
    19  
    20  	"github.com/go-jose/go-jose/v3"
    21  	"github.com/go-jose/go-jose/v3/jwt"
    22  
    23  	"github.com/livekit/protocol/livekit"
    24  )
    25  
    26  const (
    27  	defaultValidDuration = 6 * time.Hour
    28  )
    29  
    30  // AccessToken produces token signed with API key and secret
    31  type AccessToken struct {
    32  	apiKey   string
    33  	secret   string
    34  	grant    ClaimGrants
    35  	validFor time.Duration
    36  }
    37  
    38  func NewAccessToken(key string, secret string) *AccessToken {
    39  	return &AccessToken{
    40  		apiKey: key,
    41  		secret: secret,
    42  	}
    43  }
    44  
    45  func (t *AccessToken) SetIdentity(identity string) *AccessToken {
    46  	t.grant.Identity = identity
    47  	return t
    48  }
    49  
    50  func (t *AccessToken) SetValidFor(duration time.Duration) *AccessToken {
    51  	t.validFor = duration
    52  	return t
    53  }
    54  
    55  func (t *AccessToken) SetName(name string) *AccessToken {
    56  	t.grant.Name = name
    57  	return t
    58  }
    59  
    60  func (t *AccessToken) SetKind(kind livekit.ParticipantInfo_Kind) *AccessToken {
    61  	t.grant.SetParticipantKind(kind)
    62  	return t
    63  }
    64  
    65  // Deprecated: use SetVideoGrant instead
    66  func (t *AccessToken) AddGrant(grant *VideoGrant) *AccessToken {
    67  	return t.SetVideoGrant(grant)
    68  }
    69  
    70  func (t *AccessToken) SetVideoGrant(grant *VideoGrant) *AccessToken {
    71  	t.grant.Video = grant
    72  	return t
    73  }
    74  
    75  // Deprecated: use SetSIPGrant instead
    76  func (t *AccessToken) AddSIPGrant(grant *SIPGrant) *AccessToken {
    77  	return t.SetSIPGrant(grant)
    78  }
    79  
    80  func (t *AccessToken) SetSIPGrant(grant *SIPGrant) *AccessToken {
    81  	t.grant.SIP = grant
    82  	return t
    83  }
    84  
    85  func (t *AccessToken) SetAgentGrant(grant *AgentGrant) *AccessToken {
    86  	t.grant.Agent = grant
    87  	return t
    88  }
    89  
    90  func (t *AccessToken) SetMetadata(md string) *AccessToken {
    91  	t.grant.Metadata = md
    92  	return t
    93  }
    94  
    95  func (t *AccessToken) SetAttributes(attrs map[string]string) *AccessToken {
    96  	if len(attrs) == 0 {
    97  		return t
    98  	}
    99  	if t.grant.Attributes == nil {
   100  		t.grant.Attributes = make(map[string]string)
   101  	}
   102  	for k, v := range attrs {
   103  		t.grant.Attributes[k] = v
   104  	}
   105  	return t
   106  }
   107  
   108  func (t *AccessToken) SetSha256(sha string) *AccessToken {
   109  	t.grant.Sha256 = sha
   110  	return t
   111  }
   112  
   113  func (t *AccessToken) SetRoomPreset(preset string) *AccessToken {
   114  	t.grant.RoomPreset = preset
   115  	return t
   116  }
   117  
   118  func (t *AccessToken) SetRoomConfig(config *livekit.RoomConfiguration) *AccessToken {
   119  	if config == nil {
   120  		t.grant.RoomConfig = nil
   121  	} else {
   122  		t.grant.RoomConfig = (*RoomConfiguration)(config)
   123  	}
   124  	return t
   125  }
   126  
   127  // SetAgents is a shortcut for setting agents in room configuration
   128  func (t *AccessToken) SetAgents(agents ...*livekit.RoomAgentDispatch) *AccessToken {
   129  	if t.grant.RoomConfig == nil {
   130  		t.grant.RoomConfig = &RoomConfiguration{}
   131  	}
   132  	t.grant.RoomConfig.Agents = agents
   133  	return t
   134  }
   135  
   136  func (t *AccessToken) GetGrants() *ClaimGrants {
   137  	return &t.grant
   138  }
   139  
   140  func (t *AccessToken) ToJWT() (string, error) {
   141  	if t.apiKey == "" || t.secret == "" {
   142  		return "", ErrKeysMissing
   143  	}
   144  
   145  	if t.grant.RoomConfig != nil {
   146  		if err := t.grant.RoomConfig.CheckCredentials(); err != nil {
   147  			return "", err
   148  		}
   149  	}
   150  
   151  	sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: []byte(t.secret)},
   152  		(&jose.SignerOptions{}).WithType("JWT"))
   153  	if err != nil {
   154  		return "", err
   155  	}
   156  
   157  	validFor := defaultValidDuration
   158  	if t.validFor > 0 {
   159  		validFor = t.validFor
   160  	}
   161  
   162  	cl := jwt.Claims{
   163  		Issuer:    t.apiKey,
   164  		NotBefore: jwt.NewNumericDate(time.Now()),
   165  		Expiry:    jwt.NewNumericDate(time.Now().Add(validFor)),
   166  		Subject:   t.grant.Identity,
   167  	}
   168  	return jwt.Signed(sig).Claims(cl).Claims(&t.grant).CompactSerialize()
   169  }