mirror of
https://github.com/versity/versitygw.git
synced 2026-07-20 15:02:23 +00:00
feat: add group-based role mapping for FreeIPA IAM
FreeIPA users were always assigned RoleUser regardless of their group membership. This adds --ipa-admin-group-cn so that members of a specified FreeIPA group are automatically granted the admin role, and --ipa-enable-userplus to elevate the default role to userplus for all IPA users. The user_show RPC is updated to request all attributes so that memberof_group is reliably returned.
This commit is contained in:
+3
-1
@@ -152,6 +152,8 @@ type Opts struct {
|
||||
IpaVaultName string
|
||||
IpaUser string
|
||||
IpaPassword string
|
||||
IpaAdminGroupCN string
|
||||
IpaEnableUserPlus bool
|
||||
IpaInsecure bool
|
||||
}
|
||||
|
||||
@@ -179,7 +181,7 @@ func New(o *Opts) (IAMService, error) {
|
||||
o.VaultServerCert, o.VaultClientCert, o.VaultClientCertKey)
|
||||
fmt.Printf("initializing Vault IAM with %q\n", o.VaultEndpointURL)
|
||||
case o.IpaHost != "":
|
||||
svc, err = NewIpaIAMService(o.RootAccount, o.IpaHost, o.IpaVaultName, o.IpaUser, o.IpaPassword, o.IpaInsecure)
|
||||
svc, err = NewIpaIAMService(o.RootAccount, o.IpaHost, o.IpaVaultName, o.IpaUser, o.IpaPassword, o.IpaAdminGroupCN, o.IpaEnableUserPlus, o.IpaInsecure)
|
||||
fmt.Printf("initializing IPA IAM with %q\n", o.IpaHost)
|
||||
default:
|
||||
// if no iam options selected, default to the single user mode
|
||||
|
||||
+26
-13
@@ -49,21 +49,25 @@ type IpaIAMService struct {
|
||||
vaultName string
|
||||
username string
|
||||
password string
|
||||
adminGroupCN string
|
||||
enableUserPlus bool
|
||||
kraTransportKey *rsa.PublicKey
|
||||
rootAcc Account
|
||||
}
|
||||
|
||||
var _ IAMService = &IpaIAMService{}
|
||||
|
||||
func NewIpaIAMService(rootAcc Account, host, vaultName, username, password string, isInsecure bool) (*IpaIAMService, error) {
|
||||
func NewIpaIAMService(rootAcc Account, host, vaultName, username, password, adminGroupCN string, enableUserPlus, isInsecure bool) (*IpaIAMService, error) {
|
||||
ipa := IpaIAMService{
|
||||
id: 0,
|
||||
version: IpaVersion,
|
||||
host: host,
|
||||
vaultName: vaultName,
|
||||
username: username,
|
||||
password: password,
|
||||
rootAcc: rootAcc,
|
||||
id: 0,
|
||||
version: IpaVersion,
|
||||
host: host,
|
||||
vaultName: vaultName,
|
||||
username: username,
|
||||
password: password,
|
||||
adminGroupCN: adminGroupCN,
|
||||
enableUserPlus: enableUserPlus,
|
||||
rootAcc: rootAcc,
|
||||
}
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
@@ -124,15 +128,16 @@ func (ipa *IpaIAMService) GetUserAccount(access string) (Account, error) {
|
||||
return ipa.rootAcc, nil
|
||||
}
|
||||
|
||||
req, err := ipa.newRequest("user_show/1", []string{access}, map[string]any{})
|
||||
req, err := ipa.newRequest("user_show/1", []string{access}, map[string]any{"all": true})
|
||||
if err != nil {
|
||||
return Account{}, fmt.Errorf("ipa user_show: %w", err)
|
||||
}
|
||||
|
||||
userResult := struct {
|
||||
Gidnumber []string
|
||||
Uidnumber []string
|
||||
PidNumber []string
|
||||
Gidnumber []string `json:"gidnumber"`
|
||||
Uidnumber []string `json:"uidnumber"`
|
||||
PidNumber []string `json:"pidnumber"`
|
||||
MemberOfGroup []string `json:"memberof_group"`
|
||||
}{}
|
||||
|
||||
err = ipa.rpc(req, &userResult)
|
||||
@@ -153,9 +158,17 @@ func (ipa *IpaIAMService) GetUserAccount(access string) (Account, error) {
|
||||
return Account{}, err
|
||||
}
|
||||
|
||||
role := RoleUser
|
||||
if ipa.enableUserPlus {
|
||||
role = RoleUserPlus
|
||||
}
|
||||
if ipa.adminGroupCN != "" && slices.Contains(userResult.MemberOfGroup, ipa.adminGroupCN) {
|
||||
role = RoleAdmin
|
||||
}
|
||||
|
||||
account := Account{
|
||||
Access: access,
|
||||
Role: RoleUser,
|
||||
Role: role,
|
||||
UserID: uid,
|
||||
GroupID: gid,
|
||||
ProjectID: pId,
|
||||
|
||||
Reference in New Issue
Block a user