forked from Deuxfleurs/bottin
Refactor & add case normalization logic to putAttributes
This commit is contained in:
parent
1a20a64eff
commit
99d8955ab3
4 changed files with 87 additions and 46 deletions
2
main.go
2
main.go
|
@ -74,8 +74,6 @@ type State struct {
|
|||
login Login
|
||||
}
|
||||
|
||||
type Entry map[string][]string
|
||||
|
||||
var configFlag = flag.String("config", "./config.json", "Configuration file path")
|
||||
var resyncFlag = flag.Bool("resync", false, "Check and re-synchronize memberOf values before launch")
|
||||
|
||||
|
|
3
read.go
3
read.go
|
@ -17,11 +17,14 @@ func (server *Server) getAttribute(dn string, attr string) ([]string, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// List all attributes of the object, this is needed because the attribute we are
|
||||
// looking for can exist with different cases than the one specified here
|
||||
pairs, _, err := server.kv.List(path+"/attribute=", &server.readOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Collect values for the attribute, case-insensitively
|
||||
values := []string{}
|
||||
for _, pair := range pairs {
|
||||
if strings.EqualFold(pair.Key, path+"/attribute="+attr) {
|
||||
|
|
92
util.go
92
util.go
|
@ -11,6 +11,13 @@ import (
|
|||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// DNs ----
|
||||
|
||||
type dnComponent struct {
|
||||
Type string
|
||||
Value string
|
||||
}
|
||||
|
||||
func dnToConsul(dn string) (string, error) {
|
||||
if strings.Contains(dn, "/") {
|
||||
return "", fmt.Errorf("DN %s contains a /", dn)
|
||||
|
@ -45,6 +52,48 @@ func consulToDN(key string) (string, string, error) {
|
|||
return "", "", fmt.Errorf("Consul key %s does not end with attribute=something", key)
|
||||
}
|
||||
|
||||
func parseDN(dn string) ([]dnComponent, error) {
|
||||
rdns := strings.Split(dn, ",")
|
||||
|
||||
ret := []dnComponent{}
|
||||
|
||||
for _, rdn := range rdns {
|
||||
splits := strings.Split(rdn, "=")
|
||||
if len(splits) != 2 {
|
||||
return nil, fmt.Errorf("Wrong DN component: %s (expected type=value)", rdn)
|
||||
}
|
||||
ret = append(ret, dnComponent{
|
||||
Type: strings.ToLower(strings.TrimSpace(splits[0])),
|
||||
Value: strings.ToLower(strings.TrimSpace(splits[1])),
|
||||
})
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func unparseDN(path []dnComponent) string {
|
||||
ret := ""
|
||||
for _, c := range path {
|
||||
if ret != "" {
|
||||
ret = ret + ","
|
||||
}
|
||||
ret = ret + c.Type + "=" + c.Value
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func canonicalDN(dn string) (string, error) {
|
||||
path, err := parseDN(dn)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return unparseDN(path), nil
|
||||
}
|
||||
|
||||
// Values
|
||||
|
||||
type Entry map[string][]string
|
||||
|
||||
func parseValue(value []byte) ([]string, error) {
|
||||
val := []string{}
|
||||
err := json.Unmarshal(value, &val)
|
||||
|
@ -82,49 +131,6 @@ func parseConsulResult(data []*consul.KVPair) (map[string]Entry, error) {
|
|||
return aggregator, nil
|
||||
}
|
||||
|
||||
type DNComponent struct {
|
||||
Type string
|
||||
Value string
|
||||
}
|
||||
|
||||
func parseDN(dn string) ([]DNComponent, error) {
|
||||
rdns := strings.Split(dn, ",")
|
||||
|
||||
ret := []DNComponent{}
|
||||
|
||||
for _, rdn := range rdns {
|
||||
splits := strings.Split(rdn, "=")
|
||||
if len(splits) != 2 {
|
||||
return nil, fmt.Errorf("Wrong DN component: %s (expected type=value)", rdn)
|
||||
}
|
||||
ret = append(ret, DNComponent{
|
||||
Type: strings.ToLower(strings.TrimSpace(splits[0])),
|
||||
Value: strings.ToLower(strings.TrimSpace(splits[1])),
|
||||
})
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func unparseDN(path []DNComponent) string {
|
||||
ret := ""
|
||||
for _, c := range path {
|
||||
if ret != "" {
|
||||
ret = ret + ","
|
||||
}
|
||||
ret = ret + c.Type + "=" + c.Value
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func canonicalDN(dn string) (string, error) {
|
||||
path, err := parseDN(dn)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return unparseDN(path), nil
|
||||
}
|
||||
|
||||
func checkRestrictedAttr(attr string) error {
|
||||
RESTRICTED_ATTRS := []string{
|
||||
ATTR_MEMBEROF,
|
||||
|
|
36
write.go
36
write.go
|
@ -19,7 +19,31 @@ func (server *Server) putAttributes(dn string, attrs Entry) error {
|
|||
return err
|
||||
}
|
||||
|
||||
for k, valuesNC := range attrs {
|
||||
// Normalize attribute names: if we have several times the same attr
|
||||
// but with different cases, put that in the same attr
|
||||
normalized := make(Entry)
|
||||
for k, values := range attrs {
|
||||
found := false
|
||||
for k2 := range normalized {
|
||||
if strings.EqualFold(k, k2) {
|
||||
normalized[k2] = append(normalized[k2], values...)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
normalized[k] = values
|
||||
}
|
||||
}
|
||||
|
||||
// Retreieve previously existing attributes, which we will use to delete
|
||||
// entries with the wrong case
|
||||
previous_pairs, _, err := server.kv.List(prefix + "/attribute=", &server.readOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for k, valuesNC := range normalized {
|
||||
path := prefix + "/attribute=" + k
|
||||
|
||||
// Trim spaces and remove empty values
|
||||
|
@ -31,6 +55,16 @@ func (server *Server) putAttributes(dn string, attrs Entry) error {
|
|||
}
|
||||
}
|
||||
|
||||
// If previously existing pairs with the wrong case exist, delete them
|
||||
for _, prev_pair := range previous_pairs {
|
||||
if strings.EqualFold(prev_pair.Key, path) && prev_pair.Key != path {
|
||||
_, err := server.kv.Delete(prev_pair.Key, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have zero values, delete associated k/v pair
|
||||
// Otherwise, write new values
|
||||
if len(values) == 0 {
|
||||
|
|
Loading…
Reference in a new issue