diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index 9687e53..5f4b8af 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -1781,7 +1781,11 @@ func handleClientMessage(c *webClient, m clientMessage) error { if tok.Group != c.group.Name() { return terror("error", "wrong group in token") } - + if tok.IncludeSubgroups { + return terror("error", + "hierarchical token not allowed", + ) + } if tok.Expires == nil { return terror("error", "token doesn't expire") } @@ -1837,6 +1841,7 @@ func handleClientMessage(c *webClient, m clientMessage) error { return terror("error", err.Error()) } if tok.Group != "" || tok.Username != nil || + tok.IncludeSubgroups || tok.Permissions != nil || tok.IssuedBy != nil || tok.IssuedAt != nil { diff --git a/token/stateful.go b/token/stateful.go index 9c11d64..2893b49 100644 --- a/token/stateful.go +++ b/token/stateful.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "sort" + "strings" "sync" "time" ) @@ -16,26 +17,28 @@ var ErrTagMismatch = errors.New("tag mismatch") // A stateful token type Stateful struct { - Token string `json:"token"` - Group string `json:"group"` - Username *string `json:"username,omitempty"` - Permissions []string `json:"permissions"` - Expires *time.Time `json:"expires,omitempty"` - NotBefore *time.Time `json:"not-before,omitempty"` - IssuedAt *time.Time `json:"issuedAt,omitempty"` - IssuedBy *string `json:"issuedBy,omitempty"` + Token string `json:"token"` + Group string `json:"group"` + IncludeSubgroups bool `json:"includeSubgroups,omitempty"` + Username *string `json:"username,omitempty"` + Permissions []string `json:"permissions"` + Expires *time.Time `json:"expires,omitempty"` + NotBefore *time.Time `json:"not-before,omitempty"` + IssuedAt *time.Time `json:"issuedAt,omitempty"` + IssuedBy *string `json:"issuedBy,omitempty"` } func (token *Stateful) Clone() *Stateful { return &Stateful{ - Token: token.Token, - Group: token.Group, - Username: token.Username, - Permissions: append([]string(nil), token.Permissions...), - Expires: token.Expires, - NotBefore: token.NotBefore, - IssuedAt: token.IssuedAt, - IssuedBy: token.IssuedBy, + Token: token.Token, + Group: token.Group, + IncludeSubgroups: token.IncludeSubgroups, + Username: token.Username, + Permissions: append([]string(nil), token.Permissions...), + Expires: token.Expires, + NotBefore: token.NotBefore, + IssuedAt: token.IssuedAt, + IssuedBy: token.IssuedBy, } } @@ -83,8 +86,21 @@ func Get(token string) (*Stateful, string, error) { return tokens.Get(token) } +func (token *Stateful) match(group string) bool { + if group == "" { + return false + } + if group == token.Group { + return true + } + if token.IncludeSubgroups { + return strings.HasPrefix(group, token.Group + "/") + } + return false +} + func (token *Stateful) Check(host, group string, username *string) (string, []string, error) { - if token.Group == "" || group != token.Group { + if !token.match(group) { return "", nil, errors.New("token for bad group") } now := time.Now() diff --git a/token/stateful_test.go b/token/stateful_test.go index 8b90cfc..c42b4ee 100644 --- a/token/stateful_test.go +++ b/token/stateful_test.go @@ -72,6 +72,14 @@ func TestStatefulCheck(t *testing.T) { Expires: &future, NotBefore: &nearFuture, } + token5 := &Stateful{ + Token: "token", + Group: "group", + IncludeSubgroups: true, + Username: &user, + Permissions: []string{"present", "message"}, + Expires: &future, + } success := []struct { token *Stateful @@ -107,6 +115,20 @@ func TestStatefulCheck(t *testing.T) { expUsername: "", expPermissions: []string{"present", "message"}, }, + { + token: token5, + group: "group", + username: &user, + expUsername: "user", + expPermissions: []string{"present", "message"}, + }, + { + token: token5, + group: "group/subgroup", + username: &user, + expUsername: "user", + expPermissions: []string{"present", "message"}, + }, } for i, s := range success { @@ -139,6 +161,11 @@ func TestStatefulCheck(t *testing.T) { group: "group", username: &user, }, + { + token: token5, + group: "groups", + username: &user, + }, } for i, s := range failure {