Implement DeleteUser support for the Graph LDAP backend
This commit is contained in:
@@ -12,6 +12,9 @@ type Backend interface {
|
||||
// CreateUser creates a given user in the identity backend.
|
||||
CreateUser(ctx context.Context, user libregraph.User) (*libregraph.User, error)
|
||||
|
||||
// DeleteUser deletes a given user, identified by username or id, from the backend
|
||||
DeleteUser(ctx context.Context, nameOrId string) error
|
||||
|
||||
GetUser(ctx context.Context, nameOrId string) (*libregraph.User, error)
|
||||
GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error)
|
||||
|
||||
|
||||
@@ -25,6 +25,11 @@ func (i *CS3) CreateUser(ctx context.Context, user libregraph.User) (*libregraph
|
||||
return nil, errorcode.New(errorcode.NotSupported, "not implemented")
|
||||
}
|
||||
|
||||
// DeleteUser implements the Backend Interface. It's currently not supported for the CS3 backend
|
||||
func (i *CS3) DeleteUser(ctx context.Context, nameOrID string) error {
|
||||
return errorcode.New(errorcode.NotSupported, "not implemented")
|
||||
}
|
||||
|
||||
func (i *CS3) GetUser(ctx context.Context, userID string) (*libregraph.User, error) {
|
||||
client, err := pool.GetGatewayServiceClient(i.Config.Address)
|
||||
if err != nil {
|
||||
|
||||
@@ -146,6 +146,20 @@ func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregrap
|
||||
return i.createUserModelFromLDAP(e), nil
|
||||
}
|
||||
|
||||
// DeleteUser implements the Backend Interface. It permanently deletes a User identified
|
||||
// by name or id from the LDAP server
|
||||
func (i *LDAP) DeleteUser(ctx context.Context, nameOrID string) error {
|
||||
e, err := i.getLDAPUserByNameOrID(nameOrID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dr := ldap.DelRequest{DN: e.DN}
|
||||
if err = i.conn.Del(&dr); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *LDAP) getUserByDN(dn string) (*ldap.Entry, error) {
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
dn, ldap.ScopeBaseObject, ldap.NeverDerefAliases, 1, 0, false,
|
||||
@@ -173,12 +187,11 @@ func (i *LDAP) getUserByDN(dn string) (*ldap.Entry, error) {
|
||||
return res.Entries[0], nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUser(ctx context.Context, userID string) (*libregraph.User, error) {
|
||||
i.logger.Debug().Str("backend", "ldap").Msg("GetUser")
|
||||
userID = ldap.EscapeFilter(userID)
|
||||
func (i *LDAP) getLDAPUserByNameOrID(nameOrID string) (*ldap.Entry, error) {
|
||||
nameOrID = ldap.EscapeFilter(nameOrID)
|
||||
searchRequest := ldap.NewSearchRequest(
|
||||
i.userBaseDN, i.userScope, ldap.NeverDerefAliases, 1, 0, false,
|
||||
fmt.Sprintf("(&%s(|(%s=%s)(%s=%s)))", i.userFilter, i.userAttributeMap.userName, userID, i.userAttributeMap.id, userID),
|
||||
fmt.Sprintf("(&%s(|(%s=%s)(%s=%s)))", i.userFilter, i.userAttributeMap.userName, nameOrID, i.userAttributeMap.id, nameOrID),
|
||||
[]string{
|
||||
i.userAttributeMap.displayName,
|
||||
i.userAttributeMap.id,
|
||||
@@ -194,9 +207,9 @@ func (i *LDAP) GetUser(ctx context.Context, userID string) (*libregraph.User, er
|
||||
var errmsg string
|
||||
if lerr, ok := err.(*ldap.Error); ok {
|
||||
if lerr.ResultCode == ldap.LDAPResultSizeLimitExceeded {
|
||||
errmsg = fmt.Sprintf("too many results searching for user '%s'", userID)
|
||||
errmsg = fmt.Sprintf("too many results searching for user '%s'", nameOrID)
|
||||
i.logger.Debug().Str("backend", "ldap").Err(lerr).
|
||||
Str("user", userID).Msg("too many results searching for user")
|
||||
Str("user", nameOrID).Msg("too many results searching for user")
|
||||
}
|
||||
}
|
||||
return nil, errorcode.New(errorcode.ItemNotFound, errmsg)
|
||||
@@ -205,7 +218,16 @@ func (i *LDAP) GetUser(ctx context.Context, userID string) (*libregraph.User, er
|
||||
return nil, errorcode.New(errorcode.ItemNotFound, "not found")
|
||||
}
|
||||
|
||||
return i.createUserModelFromLDAP(res.Entries[0]), nil
|
||||
return res.Entries[0], nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUser(ctx context.Context, nameOrID string) (*libregraph.User, error) {
|
||||
i.logger.Debug().Str("backend", "ldap").Msg("GetUser")
|
||||
e, err := i.getLDAPUserByNameOrID(nameOrID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.createUserModelFromLDAP(e), nil
|
||||
}
|
||||
|
||||
func (i *LDAP) GetUsers(ctx context.Context, queryParam url.Values) ([]*libregraph.User, error) {
|
||||
|
||||
@@ -171,8 +171,13 @@ func (c ConnWithReconnect) Add(a *ldap.AddRequest) error {
|
||||
return conn.Add(a)
|
||||
}
|
||||
|
||||
func (c ConnWithReconnect) Del(*ldap.DelRequest) error {
|
||||
return ldap.NewError(ldap.LDAPResultNotSupported, fmt.Errorf("not implemented"))
|
||||
func (c ConnWithReconnect) Del(d *ldap.DelRequest) error {
|
||||
conn, err := c.GetConnection()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return conn.Del(d)
|
||||
}
|
||||
|
||||
func (c ConnWithReconnect) Modify(*ldap.ModifyRequest) error {
|
||||
|
||||
@@ -70,6 +70,7 @@ func NewService(opts ...Option) Service {
|
||||
r.Post("/", svc.PostUser)
|
||||
r.Route("/{userID}", func(r chi.Router) {
|
||||
r.Get("/", svc.GetUser)
|
||||
r.Delete("/", svc.DeleteUser)
|
||||
})
|
||||
})
|
||||
r.Route("/groups", func(r chi.Router) {
|
||||
|
||||
@@ -97,6 +97,32 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, user)
|
||||
}
|
||||
|
||||
func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
userID := chi.URLParam(r, "userID")
|
||||
userID, err := url.PathUnescape(userID)
|
||||
if err != nil {
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed")
|
||||
}
|
||||
|
||||
if userID == "" {
|
||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
|
||||
return
|
||||
}
|
||||
|
||||
err = g.identityBackend.DeleteUser(r.Context(), userID)
|
||||
|
||||
if err != nil {
|
||||
var errcode errorcode.Error
|
||||
if errors.As(err, &errcode) {
|
||||
errcode.Render(w, r)
|
||||
} else {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
}
|
||||
render.Status(r, http.StatusNoContent)
|
||||
render.NoContent(w, r)
|
||||
}
|
||||
|
||||
func isNilOrEmpty(s *string) bool {
|
||||
return s == nil || *s == ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user