mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-21 23:14:26 +00:00
# Which Problems Are Solved In the context of moving our datastore to relational tables, Identity Provider Intents have no definition of a relational table nor any DB API that can be used to store the IDP intents as relational objects. # How the Problems Are Solved The PR follows the guidelines left in #11190 - A table `zitadel.identity_provider_intents` is created: it defines its relational constraints (foreign keys) with the other tables, as well as an ENUM to represent the state of the intent. - An IDP Intent repository has been created, which offers CRUD operations implemented as `Create`, `Get`, `Update` and `Delete` methods for the IDP intent. - The repository also defines all columns and conditions useful for performing DB operations on the IDP intents. - DB mocks have been added as well to ease testing on the `domain` package. - Reduction functions have been implemented for the existing IDP events so to keep the relational table in sync with the event store. # Additional Changes To allow testing LDAP intent flow, the `Session.FetchUser()` method has been extracted to a separate file. A corresponding mock has been created as well in `fetch_user_mock.go`. The files are mutually excluded and added at build time through go build tags: the mock is added when the `integration` tag is specified, while the real implementation is added when the same tag IS NOT added to the build tags. # Additional Context - Closes #11190 --------- Co-authored-by: Livio Spring <[email protected]> Co-authored-by: Silvan <[email protected]>
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
//go:build !integration
|
|
|
|
package ldap
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/go-ldap/ldap/v3"
|
|
|
|
"github.com/zitadel/zitadel/internal/idp"
|
|
)
|
|
|
|
// FetchUser implements the [idp.Session] interface.
|
|
func (s *Session) FetchUser(_ context.Context) (_ idp.User, err error) {
|
|
var user *ldap.Entry
|
|
for _, server := range s.Provider.servers {
|
|
user, err = tryBind(server,
|
|
s.Provider.startTLS,
|
|
s.Provider.bindDN,
|
|
s.Provider.bindPassword,
|
|
s.Provider.baseDN,
|
|
s.Provider.getNecessaryAttributes(),
|
|
s.Provider.userObjectClasses,
|
|
s.Provider.userFilters,
|
|
s.User,
|
|
s.Password,
|
|
s.Provider.timeout,
|
|
s.Provider.rootCA)
|
|
// If there were invalid credentials or multiple users with the credentials cancel process
|
|
if err != nil && (errors.Is(err, ErrFailedLogin) || errors.Is(err, ErrNoSingleUser)) {
|
|
return nil, err
|
|
}
|
|
// If a user bind was successful and user is filled continue with login, otherwise try next server
|
|
if err == nil && user != nil {
|
|
break
|
|
}
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s.Entry = user
|
|
|
|
return mapLDAPEntryToUser(
|
|
user,
|
|
s.Provider.idAttribute,
|
|
s.Provider.firstNameAttribute,
|
|
s.Provider.lastNameAttribute,
|
|
s.Provider.displayNameAttribute,
|
|
s.Provider.nickNameAttribute,
|
|
s.Provider.preferredUsernameAttribute,
|
|
s.Provider.emailAttribute,
|
|
s.Provider.emailVerifiedAttribute,
|
|
s.Provider.phoneAttribute,
|
|
s.Provider.phoneVerifiedAttribute,
|
|
s.Provider.preferredLanguageAttribute,
|
|
s.Provider.avatarURLAttribute,
|
|
s.Provider.profileAttribute,
|
|
)
|
|
}
|