package rbac import ( "encoding/json" "strings" "github.com/sirupsen/logrus" "github.rackspace.com/gorax/clients/activeDirectory" "github.rackspace.com/gorax/clients/eDir" ) // GetPrivilegeLevel takes a PrivilegeLevel interface, and will validate the user against multiple // authentication types, depending on the initiating struct. // // GetPrivilegeLevel currently accepts the AD or Identity interfaces. func GetPrivilegeLevel(l PrivilegeLevel) (int, error) { return l.getLevel() } func (r Identity) getLevel() (int, error) { return getIdentityLevel(r.Client), nil } func (r AD) getLevel() (int, error) { // If there is no Redis key passed into the client, communicate with // Active Directory directly. if r.RedisKey == "" { logrus.Errorf("rbac:getLevel:no Redis key, cannot use a cache") u, err := gatherFromAD(r.User, r.conn) if err != nil { return BasicRead, err } return getADLevel(u), nil } // If we do have a Redis key, interface with Redis for UserGroups and fallback // to Active Directory when the Redis key is expired or doesn't exist. var ( u activeDirectory.UserGroup err error ) // Attempt to read user roles from redis, and return the user level if // we are successful (no non-nil errors) if s, err := readRedis(r.User, r.RedisKey); err == nil { if err := json.NewDecoder(strings.NewReader(s)).Decode(&u); err == nil { return getADLevel(u), nil } } // If we get here, we failed gathering UserGroup information from Redis. // Proceed with getting information directly from Active Directory. u, err = gatherFromAD(r.User, r.conn) if err != nil { return BasicRead, err } // Write the UserGroup information from Active Directory into Redis. // If there was an error, log to terminal, but still continue. if err = writeRedis(u, r.RedisKey); err != nil { logrus.Errorf("rbac:getLevel:writeRedis:%s", err) } return getADLevel(u), nil } func (r EDir) getLevel() (int, error) { if r.RedisKey != "" { s, err := readRedis(r.User, r.RedisKey) var u *eDir.UserGroup err = json.Unmarshal([]byte(s), &u) if err != nil { u, err = gatherFromEdir(r.User, r.Bind) if err != nil { return BasicRead, err } _ = writeRedis(u, r.RedisKey) } return getEdirLevel(u), nil } u, err := gatherFromEdir(r.User, r.Bind) if err != nil { return BasicRead, err } return getEdirLevel(u), nil }