Implement postgres version of scopeStore.
Update the authd server to use postgres as its scopeStore, instead of memstore.
panic when starting the authd server if the CreateScopes call fails. This
should, ideally, ignore ErrScopeAlreadyExists errors, but does not as of this
commit.
Update the simple.gotmpl template to properly display scopes, after switching to
the Scope type instead of simply passing around the string the client supplied
broke the template and I never bothered fixing it.
Update the updateScopes method on the scopeStore (and the corresponding
UpdateScopes method on the Context type) to be updateScope/UpdateScope.
Operating on several scopes at a time like that is simply too challenging in
SQL and I can't justify the complexity with a use case.
Add a helper method to ScopeChange called Empty(), which returns true if the
ScopeChange is full of nil values.
Remove the ID from the ScopeChange type, because we're no longer accepting
multiple ScopeChange types in UpdateScope, so we can supply that information
outside the ScopeChange, which matches the rest of our update* methods.
Correct our tests in scope_test.go to correctly use the updateScope method
instead of the old updateScopes method. This generally just resulted in calling
updateScope multiple times, as opposed to just once.
Add a scope table initialization to the sql/postgres_init.sql script.
5 var scopeStores = []scopeStore{NewMemstore()}
7 func compareScopes(scope1, scope2 Scope) (success bool, field string, val1, val2 interface{}) {
8 if scope1.ID != scope2.ID {
9 return false, "ID", scope1.ID, scope2.ID
11 if scope1.Name != scope2.Name {
12 return false, "Name", scope1.Name, scope2.Name
14 if scope1.Description != scope2.Description {
15 return false, "Description", scope1.Description, scope2.Description
17 return true, "", nil, nil
20 func TestScopeInScopeStore(t *testing.T) {
24 Description: "Access to testing data.",
29 Description: "Access to minions.",
34 Description: "Access to bananas.",
36 updatedName := "Updated Scope"
37 updatedDescription := "An updated scope."
38 update := ScopeChange{
41 update2 := ScopeChange{
42 Description: &updatedDescription,
44 update3 := ScopeChange{
46 Description: &updatedDescription,
48 for _, store := range scopeStores {
49 context := Context{scopes: store}
50 retrieved, err := context.GetScopes([]string{scope.ID})
51 if len(retrieved) != 0 {
52 t.Logf("%+v", retrieved)
53 t.Errorf("Expected %d results, got %d from %T", 0, len(retrieved), store)
55 if e, ok := err.(ErrScopeNotFound); !ok {
56 t.Errorf("Expected ErrScopeNotFound, got %+v instead for %T", err, store)
59 t.Errorf("Expected the error to be in position %d, got position %d from %T", 0, e.Pos, store)
62 t.Errorf("Expected the error to be with scope %s, got %s from %T", scope.ID, e.ID, store)
65 err = context.CreateScopes([]Scope{scope})
67 t.Errorf("Error saving scope to %T: %s", store, err)
69 err = context.CreateScopes([]Scope{scope})
70 if e, ok := err.(ErrScopeAlreadyExists); !ok {
71 t.Errorf("Expected ErrScopeAlreadyExists, got %s instead for %T", err, store)
74 t.Errorf("Expected the error to be in position %d, got position %d from %T", 0, e.Pos, store)
77 t.Errorf("Expected the error to be for ID %s, got %s from %T", scope.ID, e.ID, store)
80 retrieved, err = context.GetScopes([]string{scope.ID})
82 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
84 if len(retrieved) != 1 {
85 t.Logf("%+v", retrieved)
86 t.Errorf("Expected %d results, got %d from %T", 1, len(retrieved), store)
88 success, field, val1, val2 := compareScopes(scope, retrieved[0])
90 t.Errorf("Expected %s to be %+v, got %+v from %T", field, val1, val2, store)
92 err = context.CreateScopes([]Scope{scope2, scope3})
94 t.Errorf("Unexpected error trying to create scope2 and scope3 in %T: %+v", store, err)
96 retrieved, err = context.GetScopes([]string{scope.ID, scope2.ID, scope3.ID})
98 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
100 if len(retrieved) != 3 {
101 t.Logf("%+v", retrieved)
102 t.Errorf("Expected %d results, got %d from %T", 3, len(retrieved), store)
104 for pos, s := range []Scope{scope, scope2, scope3} {
105 success, field, val1, val2 = compareScopes(s, retrieved[pos])
107 t.Errorf("Expected %s to be %+v for scope %s, got %+v from %T", field, val1, s.ID, val2, store)
110 err = context.UpdateScope(scope.ID, update)
112 t.Errorf("Unexpected error updating scope in %T: %+v", store, err)
114 scope.ApplyChange(update)
115 err = context.UpdateScope(scope2.ID, update2)
117 t.Errorf("Unexpected error updating scope in %T: %+v", store, err)
119 scope2.ApplyChange(update2)
120 err = context.UpdateScope(scope3.ID, update3)
122 t.Errorf("Unexpected error updating scope in %T: %+v", store, err)
124 scope3.ApplyChange(update3)
125 retrieved, err = context.ListScopes()
127 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
129 if len(retrieved) != 3 {
130 t.Logf("%+v", retrieved)
131 t.Errorf("Expected %d results, got %d from %T", 3, len(retrieved), store)
133 for pos, s := range []Scope{scope, scope2, scope3} {
134 success, field, val1, val2 = compareScopes(s, retrieved[pos])
136 t.Errorf("Expected %s to be %+v for scope %s, got %+v from %T", field, val1, s.ID, val2, store)
139 err = context.RemoveScopes([]string{scope.ID, scope2.ID, scope3.ID})
141 t.Errorf("Unexpected error removing scopes from %T: %+v", store, err)
143 retrieved, err = context.ListScopes()
145 t.Errorf("Unexpected error retrieving scopes from %T: %+v", store, err)
147 if len(retrieved) != 0 {
148 t.Logf("%+v", retrieved)
149 t.Errorf("Expected %d results, got %d from %T", 0, len(retrieved), store)
151 err = context.RemoveScopes([]string{scope.ID})
153 t.Errorf("No error returned removing non-existent scopes from %T", store)
155 if e, ok := err.(ErrScopeNotFound); !ok {
156 t.Errorf("Unexpected error removing non-existent scopes from %T: %+v", store, err)
159 t.Errorf("Expected error to be for scope ID in pos %d, but got %d from %T", 0, e.Pos, store)
161 if e.ID != scope.ID {
162 t.Errorf("Expected error to be for scope ID %s, but got %s from %T", scope.ID, e.ID, store)
165 err = context.UpdateScope(scope.ID, update)
167 t.Errorf("No error returned updating non-existent scopes from %T", store)
169 if e, ok := err.(ErrScopeNotFound); !ok {
170 t.Errorf("Unexpected error updating non-existent scopes from %T: %+v", store, err)
173 t.Errorf("Expected error to be for scope ID in pos %d, but got %d from %T", 0, e.Pos, store)
175 if e.ID != scope.ID {
176 t.Errorf("Expected error to be for scope ID %s, but got %s from %T", scope.ID, e.ID, store)
182 func TestScopeErrors(t *testing.T) {
183 errors := map[string]error{
184 "scope test couldn't be found": ErrScopeNotFound{ID: "test", Pos: 0},
185 "scope test already exists": ErrScopeAlreadyExists{ID: "test", Pos: 0},
187 for expectation, e := range errors {
188 if e.Error() != expectation {
189 t.Errorf("Expected %+v to produce '%s', produced '%s'", e, expectation, e.Error())