mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-20 01:14:24 +03:00
tests: add e2e LDAP tests (#466)
Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
58
.github/workflows/e2e-tests.yml
vendored
58
.github/workflows/e2e-tests.yml
vendored
@@ -72,6 +72,23 @@ jobs:
|
|||||||
- name: Load Docker image
|
- name: Load Docker image
|
||||||
run: docker load -i /tmp/docker-image.tar
|
run: docker load -i /tmp/docker-image.tar
|
||||||
|
|
||||||
|
- name: Cache LLDAP Docker image
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: lldap-cache
|
||||||
|
with:
|
||||||
|
path: /tmp/lldap-image.tar
|
||||||
|
key: lldap-stable-${{ runner.os }}
|
||||||
|
|
||||||
|
- name: Pull and save LLDAP image
|
||||||
|
if: steps.lldap-cache.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
docker pull nitnelave/lldap:stable
|
||||||
|
docker save nitnelave/lldap:stable > /tmp/lldap-image.tar
|
||||||
|
|
||||||
|
- name: Load LLDAP image from cache
|
||||||
|
if: steps.lldap-cache.outputs.cache-hit == 'true'
|
||||||
|
run: docker load < /tmp/lldap-image.tar
|
||||||
|
|
||||||
- name: Install frontend dependencies
|
- name: Install frontend dependencies
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: npm ci
|
run: npm ci
|
||||||
@@ -81,15 +98,27 @@ jobs:
|
|||||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||||
run: npx playwright install --with-deps chromium
|
run: npx playwright install --with-deps chromium
|
||||||
|
|
||||||
- name: Run Docker Container with Sqlite DB
|
- name: Create Docker network
|
||||||
|
run: docker network create pocket-id-network
|
||||||
|
|
||||||
|
- name: Setup and Configure LLDAP Server
|
||||||
|
run: |
|
||||||
|
chmod +x ./scripts/tests/setup-lldap.sh
|
||||||
|
./scripts/tests/setup-lldap.sh
|
||||||
|
|
||||||
|
- name: Run Docker Container with Sqlite DB and LDAP
|
||||||
run: |
|
run: |
|
||||||
docker run -d --name pocket-id-sqlite \
|
docker run -d --name pocket-id-sqlite \
|
||||||
|
--network pocket-id-network \
|
||||||
-p 80:80 \
|
-p 80:80 \
|
||||||
-e APP_ENV=test \
|
-e APP_ENV=test \
|
||||||
pocket-id:test
|
pocket-id:test
|
||||||
|
|
||||||
docker logs -f pocket-id-sqlite &> /tmp/backend.log &
|
docker logs -f pocket-id-sqlite &> /tmp/backend.log &
|
||||||
|
|
||||||
|
- name: Wait for backend to sync LDAP data
|
||||||
|
run: sleep 10
|
||||||
|
|
||||||
- name: Run Playwright tests
|
- name: Run Playwright tests
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: npx playwright test
|
run: npx playwright test
|
||||||
@@ -150,6 +179,23 @@ jobs:
|
|||||||
if: steps.postgres-cache.outputs.cache-hit == 'true'
|
if: steps.postgres-cache.outputs.cache-hit == 'true'
|
||||||
run: docker load < /tmp/postgres-image.tar
|
run: docker load < /tmp/postgres-image.tar
|
||||||
|
|
||||||
|
- name: Cache LLDAP Docker image
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: lldap-cache
|
||||||
|
with:
|
||||||
|
path: /tmp/lldap-image.tar
|
||||||
|
key: lldap-stable-${{ runner.os }}
|
||||||
|
|
||||||
|
- name: Pull and save LLDAP image
|
||||||
|
if: steps.lldap-cache.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
docker pull nitnelave/lldap:stable
|
||||||
|
docker save nitnelave/lldap:stable > /tmp/lldap-image.tar
|
||||||
|
|
||||||
|
- name: Load LLDAP image from cache
|
||||||
|
if: steps.lldap-cache.outputs.cache-hit == 'true'
|
||||||
|
run: docker load < /tmp/lldap-image.tar
|
||||||
|
|
||||||
- name: Download Docker image artifact
|
- name: Download Docker image artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -192,7 +238,12 @@ jobs:
|
|||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Run Docker Container with Postgres DB
|
- name: Setup and Configure LLDAP Server
|
||||||
|
run: |
|
||||||
|
chmod +x ./scripts/tests/setup-lldap.sh
|
||||||
|
./scripts/tests/setup-lldap.sh
|
||||||
|
|
||||||
|
- name: Run Docker Container with Postgres DB and LDAP
|
||||||
run: |
|
run: |
|
||||||
docker run -d --name pocket-id-postgres \
|
docker run -d --name pocket-id-postgres \
|
||||||
--network pocket-id-network \
|
--network pocket-id-network \
|
||||||
@@ -204,6 +255,9 @@ jobs:
|
|||||||
|
|
||||||
docker logs -f pocket-id-postgres &> /tmp/backend.log &
|
docker logs -f pocket-id-postgres &> /tmp/backend.log &
|
||||||
|
|
||||||
|
- name: Wait for backend to sync LDAP data
|
||||||
|
run: sleep 10
|
||||||
|
|
||||||
- name: Run Playwright tests
|
- name: Run Playwright tests
|
||||||
working-directory: ./frontend
|
working-directory: ./frontend
|
||||||
run: npx playwright test
|
run: npx playwright test
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
registerTestControllers = []func(apiGroup *gin.RouterGroup, db *gorm.DB, svc *services){
|
registerTestControllers = []func(apiGroup *gin.RouterGroup, db *gorm.DB, svc *services){
|
||||||
func(apiGroup *gin.RouterGroup, db *gorm.DB, svc *services) {
|
func(apiGroup *gin.RouterGroup, db *gorm.DB, svc *services) {
|
||||||
testService := service.NewTestService(db, svc.appConfigService, svc.jwtService)
|
testService := service.NewTestService(db, svc.appConfigService, svc.jwtService, svc.ldapService)
|
||||||
controller.NewTestController(apiGroup, testService)
|
controller.NewTestController(apiGroup, testService)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,16 @@ func (tc *TestController) resetAndSeedHandler(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := tc.TestService.SetLdapTestConfig(c.Request.Context()); err != nil {
|
||||||
|
_ = c.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tc.TestService.SyncLdap(c.Request.Context()); err != nil {
|
||||||
|
_ = c.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
tc.TestService.SetJWTKeys()
|
tc.TestService.SetJWTKeys()
|
||||||
|
|
||||||
c.Status(http.StatusNoContent)
|
c.Status(http.StatusNoContent)
|
||||||
|
|||||||
@@ -29,15 +29,16 @@ type TestService struct {
|
|||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
jwtService *JwtService
|
jwtService *JwtService
|
||||||
appConfigService *AppConfigService
|
appConfigService *AppConfigService
|
||||||
|
ldapService *LdapService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTestService(db *gorm.DB, appConfigService *AppConfigService, jwtService *JwtService) *TestService {
|
func NewTestService(db *gorm.DB, appConfigService *AppConfigService, jwtService *JwtService, ldapService *LdapService) *TestService {
|
||||||
return &TestService{db: db, appConfigService: appConfigService, jwtService: jwtService}
|
return &TestService{db: db, appConfigService: appConfigService, jwtService: jwtService, ldapService: ldapService}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocognit
|
//nolint:gocognit
|
||||||
func (s *TestService) SeedDatabase() error {
|
func (s *TestService) SeedDatabase() error {
|
||||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||||
users := []model.User{
|
users := []model.User{
|
||||||
{
|
{
|
||||||
Base: model.Base{
|
Base: model.Base{
|
||||||
@@ -238,6 +239,12 @@ func (s *TestService) SeedDatabase() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TestService) ResetDatabase() error {
|
func (s *TestService) ResetDatabase() error {
|
||||||
@@ -349,3 +356,52 @@ func (s *TestService) getCborPublicKey(base64PublicKey string) ([]byte, error) {
|
|||||||
|
|
||||||
return cborPublicKey, nil
|
return cborPublicKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SyncLdap triggers an LDAP synchronization
|
||||||
|
func (s *TestService) SyncLdap(ctx context.Context) error {
|
||||||
|
return s.ldapService.SyncAll(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLdapTestConfig writes the test LDAP config variables directly to the database.
|
||||||
|
func (s *TestService) SetLdapTestConfig(ctx context.Context) error {
|
||||||
|
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||||
|
ldapConfigs := map[string]string{
|
||||||
|
"ldapUrl": "ldap://lldap:3890",
|
||||||
|
"ldapBindDn": "uid=admin,ou=people,dc=pocket-id,dc=org",
|
||||||
|
"ldapBindPassword": "admin_password",
|
||||||
|
"ldapBase": "dc=pocket-id,dc=org",
|
||||||
|
"ldapUserSearchFilter": "(objectClass=person)",
|
||||||
|
"ldapUserGroupSearchFilter": "(objectClass=groupOfNames)",
|
||||||
|
"ldapSkipCertVerify": "true",
|
||||||
|
"ldapAttributeUserUniqueIdentifier": "uuid",
|
||||||
|
"ldapAttributeUserUsername": "uid",
|
||||||
|
"ldapAttributeUserEmail": "mail",
|
||||||
|
"ldapAttributeUserFirstName": "givenName",
|
||||||
|
"ldapAttributeUserLastName": "sn",
|
||||||
|
"ldapAttributeGroupUniqueIdentifier": "uuid",
|
||||||
|
"ldapAttributeGroupName": "uid",
|
||||||
|
"ldapAttributeGroupMember": "member",
|
||||||
|
"ldapAttributeAdminGroup": "admin_group",
|
||||||
|
"ldapSoftDeleteUsers": "true",
|
||||||
|
"ldapEnabled": "true",
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range ldapConfigs {
|
||||||
|
configVar := model.AppConfigVariable{Key: key, Value: value}
|
||||||
|
if err := tx.Create(&configVar).Error; err != nil {
|
||||||
|
return fmt.Errorf("failed to create config variable '%s': %w", key, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to set LDAP test config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.appConfigService.LoadDbConfig(ctx); err != nil {
|
||||||
|
return fmt.Errorf("failed to load app config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,47 +53,6 @@ test('Update email configuration', async ({ page }) => {
|
|||||||
await expect(page.getByLabel('API Key Expiration')).toBeChecked();
|
await expect(page.getByLabel('API Key Expiration')).toBeChecked();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Update LDAP configuration', async ({ page }) => {
|
|
||||||
await page.goto('/settings/admin/application-configuration');
|
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Expand card' }).nth(2).click();
|
|
||||||
|
|
||||||
await page.getByLabel('LDAP URL').fill('ldap://localhost:389');
|
|
||||||
await page.getByLabel('LDAP Bind DN').fill('cn=admin,dc=example,dc=com');
|
|
||||||
await page.getByLabel('LDAP Bind Password').fill('password');
|
|
||||||
await page.getByLabel('LDAP Base DN').fill('dc=example,dc=com');
|
|
||||||
await page.getByLabel('User Search Filter').fill('(objectClass=person)');
|
|
||||||
await page.getByLabel('Groups Search Filter').fill('(objectClass=groupOfUniqueNames)');
|
|
||||||
await page.getByLabel('User Unique Identifier Attribute').fill('uuid');
|
|
||||||
await page.getByLabel('Username Attribute').fill('uid');
|
|
||||||
await page.getByLabel('User Mail Attribute').fill('mail');
|
|
||||||
await page.getByLabel('User First Name Attribute').fill('givenName');
|
|
||||||
await page.getByLabel('User Last Name Attribute').fill('sn');
|
|
||||||
await page.getByLabel('Group Unique Identifier Attribute').fill('uuid');
|
|
||||||
await page.getByLabel('Group Name Attribute').fill('cn');
|
|
||||||
await page.getByLabel('Admin Group Name').fill('admin');
|
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Enable' }).click();
|
|
||||||
|
|
||||||
await expect(page.getByRole('status')).toHaveText('LDAP configuration updated successfully');
|
|
||||||
|
|
||||||
await page.reload();
|
|
||||||
|
|
||||||
await expect(page.getByRole('button', { name: 'Disable' })).toBeVisible();
|
|
||||||
await expect(page.getByLabel('LDAP URL')).toHaveValue('ldap://localhost:389');
|
|
||||||
await expect(page.getByLabel('LDAP Bind DN')).toHaveValue('cn=admin,dc=example,dc=com');
|
|
||||||
await expect(page.getByLabel('LDAP Bind Password')).toHaveValue('password');
|
|
||||||
await expect(page.getByLabel('LDAP Base DN')).toHaveValue('dc=example,dc=com');
|
|
||||||
await page.getByLabel('User Search Filter').fill('(objectClass=person)');
|
|
||||||
await page.getByLabel('Groups Search Filter').fill('(objectClass=groupOfUniqueNames)');
|
|
||||||
await expect(page.getByLabel('User Unique Identifier Attribute')).toHaveValue('uuid');
|
|
||||||
await expect(page.getByLabel('Username Attribute')).toHaveValue('uid');
|
|
||||||
await expect(page.getByLabel('User Mail Attribute')).toHaveValue('mail');
|
|
||||||
await expect(page.getByLabel('User First Name Attribute')).toHaveValue('givenName');
|
|
||||||
await expect(page.getByLabel('User Last Name Attribute')).toHaveValue('sn');
|
|
||||||
await expect(page.getByLabel('Admin Group Name')).toHaveValue('admin');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Update application images', async ({ page }) => {
|
test('Update application images', async ({ page }) => {
|
||||||
await page.goto('/settings/admin/application-configuration');
|
await page.goto('/settings/admin/application-configuration');
|
||||||
|
|
||||||
|
|||||||
83
frontend/tests/ldap.spec.ts
Normal file
83
frontend/tests/ldap.spec.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import test, { expect } from '@playwright/test';
|
||||||
|
import { cleanupBackend } from './utils/cleanup.util';
|
||||||
|
|
||||||
|
test.beforeEach(cleanupBackend);
|
||||||
|
|
||||||
|
test.describe('LDAP Integration', () => {
|
||||||
|
test('LDAP configuration is working properly', async ({ page }) => {
|
||||||
|
await page.goto('/settings/admin/application-configuration');
|
||||||
|
|
||||||
|
await page.getByRole('heading', { name: 'LDAP' }).click();
|
||||||
|
|
||||||
|
await expect(page.getByRole('button', { name: 'Disable' })).toBeVisible();
|
||||||
|
await expect(page.getByLabel('LDAP URL')).toHaveValue(/ldap:\/\/.*/);
|
||||||
|
await expect(page.getByLabel('LDAP Base DN')).not.toBeEmpty();
|
||||||
|
|
||||||
|
await expect(page.getByLabel('User Unique Identifier Attribute')).not.toBeEmpty();
|
||||||
|
await expect(page.getByLabel('Username Attribute')).not.toBeEmpty();
|
||||||
|
await expect(page.getByLabel('User Mail Attribute')).not.toBeEmpty();
|
||||||
|
await expect(page.getByLabel('Group Name Attribute')).not.toBeEmpty();
|
||||||
|
|
||||||
|
const syncButton = page.getByRole('button', { name: 'Sync now' });
|
||||||
|
await syncButton.click();
|
||||||
|
await expect(page.getByText('LDAP sync finished')).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('LDAP users are synced into PocketID', async ({ page }) => {
|
||||||
|
// Navigate to user management
|
||||||
|
await page.goto('/settings/admin/users');
|
||||||
|
|
||||||
|
// Verify the LDAP users exist
|
||||||
|
await expect(page.getByText('testuser1@pocket-id.org')).toBeVisible();
|
||||||
|
await expect(page.getByText('testuser2@pocket-id.org')).toBeVisible();
|
||||||
|
|
||||||
|
// Check LDAP user details
|
||||||
|
await page.getByRole('row', { name: 'testuser1' }).getByRole('button').click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||||
|
|
||||||
|
// Verify user source is LDAP
|
||||||
|
await expect(page.getByText('LDAP').first()).toBeVisible();
|
||||||
|
|
||||||
|
// Verify essential fields are filled
|
||||||
|
await expect(page.getByLabel('Username')).not.toBeEmpty();
|
||||||
|
await expect(page.getByLabel('Email')).not.toBeEmpty();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('LDAP groups are synced into PocketID', async ({ page }) => {
|
||||||
|
// Navigate to user groups
|
||||||
|
await page.goto('/settings/admin/user-groups');
|
||||||
|
|
||||||
|
// Verify LDAP groups exist
|
||||||
|
await expect(page.getByRole('cell', { name: 'test_group' }).first()).toBeVisible();
|
||||||
|
await expect(page.getByRole('cell', { name: 'admin_group' }).first()).toBeVisible();
|
||||||
|
|
||||||
|
// Check group details
|
||||||
|
await page.getByRole('row', { name: 'test_group' }).getByRole('button').click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||||
|
|
||||||
|
// Verify group source is LDAP
|
||||||
|
await expect(page.getByText('LDAP').first()).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('LDAP users cannot be modified in PocketID', async ({ page }) => {
|
||||||
|
// Navigate to LDAP user details
|
||||||
|
await page.goto('/settings/admin/users');
|
||||||
|
await page.getByRole('row', { name: 'testuser1' }).getByRole('button').click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||||
|
|
||||||
|
// Verify key fields are disabled
|
||||||
|
const usernameInput = page.getByLabel('Username');
|
||||||
|
await expect(usernameInput).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('LDAP groups cannot be modified in PocketID', async ({ page }) => {
|
||||||
|
// Navigate to LDAP group details
|
||||||
|
await page.goto('/settings/admin/user-groups');
|
||||||
|
await page.getByRole('row', { name: 'test_group' }).getByRole('button').click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Edit' }).click();
|
||||||
|
|
||||||
|
// Verify key fields are disabled
|
||||||
|
const nameInput = page.getByLabel('Name', { exact: true });
|
||||||
|
await expect(nameInput).toBeDisabled();
|
||||||
|
});
|
||||||
|
});
|
||||||
100
scripts/tests/setup-lldap.sh
Normal file
100
scripts/tests/setup-lldap.sh
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo 'deb http://download.opensuse.org/repositories/home:/Masgalor:/LLDAP/xUbuntu_24.04/ /' | sudo tee /etc/apt/sources.list.d/home:Masgalor:LLDAP.list
|
||||||
|
curl -fsSL https://download.opensuse.org/repositories/home:Masgalor:LLDAP/xUbuntu_24.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_Masgalor_LLDAP.gpg > /dev/null
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y lldap-cli lldap-set-password
|
||||||
|
|
||||||
|
echo "Setting up LLDAP container..."
|
||||||
|
|
||||||
|
# Run LLDAP container
|
||||||
|
docker run -d --name lldap \
|
||||||
|
--network pocket-id-network \
|
||||||
|
-p 3890:3890 \
|
||||||
|
-p 17170:17170 \
|
||||||
|
-e LLDAP_JWT_SECRET=secret \
|
||||||
|
-e LLDAP_LDAP_USER_PASS=admin_password \
|
||||||
|
-e LLDAP_LDAP_BASE_DN="dc=pocket-id,dc=org" \
|
||||||
|
nitnelave/lldap:stable
|
||||||
|
|
||||||
|
# Wait for LLDAP to start
|
||||||
|
for i in {1..15}; do
|
||||||
|
if curl -s --fail http://localhost:17170/api/healthcheck > /dev/null; then
|
||||||
|
echo "LLDAP is ready"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ $i -eq 15 ]; then
|
||||||
|
echo "LLDAP failed to start in time"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "Waiting for LLDAP... ($i/15)"
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "LLDAP container setup complete"
|
||||||
|
|
||||||
|
echo "Setting up LLDAP test data..."
|
||||||
|
|
||||||
|
# Configure LLDAP CLI connection via environment variables
|
||||||
|
export LLDAP_HTTPURL="http://localhost:17170"
|
||||||
|
export LLDAP_USERNAME="admin"
|
||||||
|
export LLDAP_PASSWORD="admin_password"
|
||||||
|
|
||||||
|
# Create test users using the user add command
|
||||||
|
echo "Creating test users..."
|
||||||
|
lldap-cli user add "testuser1" "testuser1@pocket-id.org" \
|
||||||
|
-p "password123" \
|
||||||
|
-d "Test User 1" \
|
||||||
|
-f "Test" \
|
||||||
|
-l "User"
|
||||||
|
|
||||||
|
lldap-cli user add "testuser2" "testuser2@pocket-id.org" \
|
||||||
|
-p "password123" \
|
||||||
|
-d "Test User 2" \
|
||||||
|
-f "Test2" \
|
||||||
|
-l "User2"
|
||||||
|
|
||||||
|
# Create test groups
|
||||||
|
echo "Creating test groups..."
|
||||||
|
lldap-cli group add "test_group"
|
||||||
|
sleep 1
|
||||||
|
lldap-cli group update set "test_group" "display_name" "test_group"
|
||||||
|
|
||||||
|
lldap-cli group add "admin_group"
|
||||||
|
sleep 1
|
||||||
|
lldap-cli group update set "admin_group" "display_name" "admin_group"
|
||||||
|
|
||||||
|
# Add users to groups with retry logic
|
||||||
|
echo "Adding users to groups..."
|
||||||
|
for i in {1..3}; do
|
||||||
|
echo "Attempt $i to add testuser1 to test_group"
|
||||||
|
if lldap-cli user group add "testuser1" "test_group"; then
|
||||||
|
echo "Successfully added testuser1 to test_group"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Failed to add testuser1 to test_group, retrying in 2 seconds..."
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $i -eq 3 ]; then
|
||||||
|
echo "Warning: Could not add testuser1 to test_group after 3 attempts"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for i in {1..3}; do
|
||||||
|
echo "Attempt $i to add testuser2 to admin_group"
|
||||||
|
if lldap-cli user group add "testuser2" "admin_group"; then
|
||||||
|
echo "Successfully added testuser2 to admin_group"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Failed to add testuser2 to admin_group, retrying in 2 seconds..."
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $i -eq 3 ]; then
|
||||||
|
echo "Warning: Could not add testuser2 to admin_group after 3 attempts"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "LLDAP test data setup complete"
|
||||||
Reference in New Issue
Block a user