Add support for decoding users from yaml def

This commit is contained in:
Denis Arh
2020-11-27 11:19:15 +01:00
committed by Tomaž Jerman
parent a05391c636
commit 0450b85dfc
4 changed files with 188 additions and 1 deletions
+5 -1
View File
@@ -11,6 +11,7 @@ type (
Document struct {
compose *compose
roles roleSet
users userSet
*rbacRules
}
)
@@ -28,8 +29,11 @@ func (doc *Document) UnmarshalYAML(n *yaml.Node) (err error) {
switch k.Value {
case "roles":
return v.Decode(&doc.roles)
}
case "users":
return v.Decode(&doc.users)
}
return nil
})
}
+5
View File
@@ -0,0 +1,5 @@
users:
u1: u1@example.tld
u2:
name: John Doe
email: jdoe@example.tld
+126
View File
@@ -0,0 +1,126 @@
package yaml
import (
"github.com/cortezaproject/corteza-server/system/types"
"gopkg.in/yaml.v3"
)
type (
user struct {
// when user is at least partially defined
res *types.User `yaml:",inline"`
// all known modules on a user
modules ComposeModuleSet
// module's RBAC rules
*rbacRules
}
userSet []*user
)
// UnmarshalYAML resolves set of user definitions, either sequence or map
//
// When resolving map, key is used as handle
// Also supporting { handle: name } definitions
//
func (wset *userSet) UnmarshalYAML(n *yaml.Node) error {
return each(n, func(k, v *yaml.Node) (err error) {
var (
wrap = &user{}
)
if v == nil {
return nodeErr(n, "malformed user definition")
}
wrap.res = &types.User{EmailConfirmed: true}
if isKind(v, yaml.ScalarNode) {
if k != nil {
wrap.res.Handle = k.Value
}
if err = decodeScalar(v, "user email", &wrap.res.Email); err != nil {
return
}
*wset = append(*wset, wrap)
return
}
if err = v.Decode(&wrap.res); err != nil {
return
}
if k != nil {
if wrap.res.Handle != "" {
return nodeErr(k, "cannot define handle in mapped user definition")
}
if err = decodeRef(k, "user", &wrap.res.Handle); err != nil {
return err
}
}
*wset = append(*wset, wrap)
return
})
}
//func (wset userSet) MarshalEnvoy() ([]envoy.Node, error) {
// // user usually have bunch of sub-resources defined
// nn := make([]envoy.Node, 0, len(wset)*10)
//
// for _, res := range wset {
// if tmp, err := res.MarshalEnvoy(); err != nil {
// return nil, err
// } else {
// nn = append(nn, tmp...)
// }
// }
//
// return nn, nil
//}
func (wrap *user) UnmarshalYAML(n *yaml.Node) (err error) {
if !isKind(n, yaml.MappingNode) {
return nodeErr(n, "user definition must be a map or scalar")
}
if wrap.res == nil {
wrap.res = &types.User{}
}
if err = n.Decode(&wrap.res); err != nil {
return
}
if wrap.rbacRules, err = decodeResourceAccessControl(types.UserRBACResource, n); err != nil {
return
}
return nil
}
//func (wrap user) MarshalEnvoy() ([]envoy.Node, error) {
// nn := make([]envoy.Node, 0, 1+len(wrap.modules))
// nn = append(nn, &envoy.UserNode{Ns: wrap.res})
//
// if tmp, err := wrap.modules.MarshalEnvoy(); err != nil {
// return nil, err
// } else {
// nn = append(nn, tmp...)
// }
//
// // @todo rbac
//
// //if tmp, err := wrap.rules.MarshalEnvoy(); err != nil {
// // return nil, err
// //} else {
// // nn = append(nn, tmp...)
// //}
//
// return nn, nil
//}
+52
View File
@@ -0,0 +1,52 @@
package yaml
import (
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
"testing"
)
func TestUser_UnmarshalYAML(t *testing.T) {
var (
parseString = func(src string) (*user, error) {
w := &user{}
return w, yaml.Unmarshal([]byte(src), w)
}
)
t.Run("empty", func(t *testing.T) {
req := require.New(t)
w, err := parseString(``)
req.NoError(err)
req.NotNil(w)
req.Nil(w.res)
})
t.Run("simple name", func(t *testing.T) {
req := require.New(t)
w, err := parseString(`{ name: Test }`)
req.NoError(err)
req.NotNil(w)
req.NotNil(w.res)
req.NotEmpty(w.res.Name)
})
t.Run("user 1", func(t *testing.T) {
req := require.New(t)
doc, err := parseDocument("user_1")
req.NoError(err)
req.NotNil(doc)
req.Len(doc.users, 2)
req.NotNil(doc.users[0])
req.Equal("u1@example.tld", doc.users[0].res.Email)
req.Equal("u1", doc.users[0].res.Handle)
req.NotNil(doc.users[1])
req.Equal("John Doe", doc.users[1].res.Name)
req.Equal("jdoe@example.tld", doc.users[1].res.Email)
req.Equal(true, doc.users[1].res.EmailConfirmed)
req.Equal("u2", doc.users[1].res.Handle)
})
}