func TestIsInGroupErrorCasesShouldBeIgnored(t *testing.T) { userID := model.ToUserID("*****@*****.**") groupName := "group" testcases := []struct { groups map[string]*model.AuthGroup }{ { // cyclic dependency. groups: map[string]*model.AuthGroup{ groupName: { Nested: []string{groupName}, }, }, }, { // group name does not exist. groups: map[string]*model.AuthGroup{ "nonexist": {}, }, }, } for _, tc := range testcases { seen := make(map[string]bool) actual := isInGroup(groupName, userID, tc.groups, seen) if actual { t.Errorf("isInGroup(%q, %q, %q, _) = %v; want false", groupName, userID, tc.groups, actual) } } }
// IsGroupMember returns true if a member is in a group. func IsGroupMember(c context.Context, groupName, userName string) (bool, error) { // TODO(yyanagisawa): cache coverted data, and match result. // we do not need to create map everytime. snap := &model.AuthDBSnapshot{} if err := model.CurrentAuthDBSnapshot(c, snap); err != nil { return false, err } ag := make(map[string]*model.AuthGroup, len(snap.Groups)) for _, g := range snap.Groups { ag[g.Key.StringID()] = g } seen := make(map[string]bool) return isInGroup(groupName, model.ToUserID(userName), ag, seen), nil }
func TestIsInGroupNormalCases(t *testing.T) { userID := model.ToUserID("*****@*****.**") groupName := "group" testcases := []struct { groupName string groups map[string]*model.AuthGroup expected bool }{ { // nobody in group. groups: map[string]*model.AuthGroup{ groupName: {}, }, expected: false, }, { // matched in Members. groups: map[string]*model.AuthGroup{ groupName: { Members: []string{userID}, }, }, expected: true, }, { // matched in Globs. groups: map[string]*model.AuthGroup{ groupName: { Globs: []string{userID}, }, }, expected: true, }, { // matched in Globs using globbing. groups: map[string]*model.AuthGroup{ groupName: { Globs: []string{model.ToUserID("*@example.com")}, }, }, expected: true, }, { // matched as nested group member. groups: map[string]*model.AuthGroup{ groupName: { Nested: []string{"nested"}, }, "nested": { Members: []string{userID}, }, }, expected: true, }, { // matched as nested nested group member. groups: map[string]*model.AuthGroup{ groupName: { Nested: []string{"nested"}, }, "nested": { Nested: []string{"nestednested"}, }, "nestednested": { Members: []string{userID}, }, }, expected: true, }, { // matched even if not first Member. groups: map[string]*model.AuthGroup{ groupName: { Members: []string{model.ToUserID("*****@*****.**"), userID}, }, }, expected: true, }, { // matched even if not first Glob. groups: map[string]*model.AuthGroup{ groupName: { Globs: []string{model.ToUserID("*@example.net"), model.ToUserID("*@example.com")}, }, }, expected: true, }, { // matched even if not in first Nested. groups: map[string]*model.AuthGroup{ groupName: { Nested: []string{"dummy", "nested"}, }, "dummy": {}, "nested": { Members: []string{userID}, }, }, expected: true, }, } for _, tc := range testcases { seen := make(map[string]bool) actual := isInGroup(groupName, userID, tc.groups, seen) if actual != tc.expected { t.Errorf("isInGroup(%q, %q, %q, _) = %v; want %v", groupName, userID, tc.groups, actual, tc.expected) } } }