فصل ششم: مدیریت کاربران به سبک حرفه‌ای: قدرتمند، انعطاف‌پذیر، پارسی

هدف فصل: فرمانروایی بر کاربران با ابزارهای پیشرفته

تصور کنید Nextcloud شما به یک مرکز مدیریت کاربران تبدیل شود که با چند کلیک یا دستور، صدها حساب را مدیریت می‌کند، گروه‌ها را سازمان‌دهی می‌کند، و با Active Directory (AD) به‌صورت بهینه همگام می‌شود! در این فصل، قابلیت‌های مدیریت کاربران در Nextcloud ۳۲.۰.۰ را با عملیات بالک (انبوه)، مدیریت گروه‌های پیشرفته، و ایمپورت اکسل ارتقا می‌دهیم. همچنین، تنظیمات AD را برای عملکرد بهتر بهینه می‌کنیم. آماده‌اید تا مدیریت کاربران را به یک تجربه سریع، پارسی، و حرفه‌ای تبدیل کنید؟


۶.۱ عملیات بالک: مدیریت انبوه با یک اشاره

۶.۱.۱ کنترلر عملیات بالک

فایل: apps/myapp/lib/Controller/UserController.php

<?php
namespace OCA\MyApp\Controller;

use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IUserManager;

class UserController extends Controller {
    private $userManager;

    public function __construct($appName, IRequest $request, IUserManager $userManager) {
        parent::__construct($appName, $request);
        $this->userManager = $userManager;
    }

    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     * @param array $users لیست شناسه‌های کاربری
     * @param string $quota سهمیه ذخیره‌سازی (مثل 10GB)
     * @param ?string $password رمز عبور جدید (اختیاری)
     * @return JSONResponse
     */
    public function bulkUpdate(array $users, string $quota, ?string $password = null): JSONResponse {
        $results = [];
        foreach ($users as $uid) {
            $user = $this->userManager->get($uid);
            if ($user) {
                try {
                    $user->setQuota($quota);
                    if ($password) {
                        $user->setPassword($password);
                    }
                    $results[$uid] = 'success';
                } catch (\Exception $e) {
                    $results[$uid] = 'error: ' . $e->getMessage();
                }
            } else {
                $results[$uid] = 'error: user not found';
            }
        }
        return new JSONResponse(['status' => 'completed', 'results' => $results]);
    }
}

۶.۱.۲ تعریف مسیر API

فایل: apps/myapp/appinfo/routes.php

<?php
return [
    'routes' => [
        [
            'name' => 'user#bulkUpdate',
            'url' => '/api/users/bulk',
            'verb' => 'POST'
        ]
    ]
];

تست API:

curl -X POST http://localhost:8080/index.php/apps/myapp/api/users/bulk \
    -H "Content-Type: application/json" \
    -d '{"users":["user1","user2"],"quota":"10GB","password":"newpass123"}'

۶.۲ مدیریت گروه: ساختاردهی هوشمند

۶.۲.۱ کلاس مدیریت گروه

فایل: apps/myapp/lib/GroupManager.php

<?php
namespace OCA\MyApp;

use OCP\IGroupManager;

class GroupManager {
    private $groupManager;

    public function __construct(IGroupManager $groupManager) {
        $this->groupManager = $groupManager;
    }

    public function setSubadminLevel(string $groupId, int $level): bool {
        $group = $this->groupManager->get($groupId);
        if ($group) {
            $group->setCustomData('subadmin_level', $level);
            \OC::$server->getLogger()->info("Subadmin level set to $level for group $groupId");
            return true;
        }
        return false;
    }

    public function getSubadminLevel(string $groupId): ?int {
        $group = $this->groupManager->get($groupId);
        return $group ? (int)$group->getCustomData('subadmin_level') : null;
    }
}

۶.۲.۲ ادغام در کنترلر

فایل: apps/myapp/lib/Controller/GroupController.php

<?php
namespace OCA\MyApp\Controller;

use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCA\MyApp\GroupManager;

class GroupController extends Controller {
    private $groupManager;

    public function __construct($appName, IRequest $request, GroupManager $groupManager) {
        parent::__construct($appName, $request);
        $this->groupManager = $groupManager;
    }

    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     */
    public function setLevel(string $groupId, int $level): JSONResponse {
        if ($this->groupManager->setSubadminLevel($groupId, $level)) {
            return new JSONResponse(['status' => 'success', 'group' => $groupId, 'level' => $level]);
        }
        return new JSONResponse(['status' => 'error', 'message' => 'Group not found'], 404);
    }
}

۶.۲.۳ تعریف مسیر API

فایل: apps/myapp/appinfo/routes.php

[
    'name' => 'group#setLevel',
    'url' => '/api/groups/{groupId}/level',
    'verb' => 'POST'
]

تست API:

curl -X POST http://localhost:8080/index.php/apps/myapp/api/groups/developers/level \
    -H "Content-Type: application/json" \
    -d '{"level": 3}'

۶.۳ ایمپورت اکسل: ورود انبوه کاربران

۶.۳.۱ دستور ایمپورت

فایل: apps/myapp/lib/Command/ImportUsers.php

<?php
namespace OCA\MyApp\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use OCP\IUserManager;
use PhpOffice\PhpSpreadsheet\IOFactory;

class ImportUsers extends Command {
    protected $userManager;

    public function __construct(IUserManager $userManager) {
        parent::__construct();
        $this->userManager = $userManager;
    }

    protected function configure() {
        $this->setName('user:import-excel')
             ->setDescription('ایمپورت کاربران از فایل اکسل')
             ->addArgument('file', InputArgument::REQUIRED, 'مسیر فایل اکسل (ستون‌ها: username, password, email)');
    }

    protected function execute(InputInterface $input, OutputInterface $output) {
        try {
            $file = $input->getArgument('file');
            $spreadsheet = IOFactory::load($file);
            $sheet = $spreadsheet->getActiveSheet();
            $successCount = 0;
            $errors = [];

            foreach ($sheet->getRowIterator(2) as $row) {
                $data = $row->toArray();
                $username = $data[0] ?? null;
                $password = $data[1] ?? null;
                $email = $data[2] ?? null;

                if ($username && $password) {
                    try {
                        $user = $this->userManager->createUser($username, $password);
                        if ($email) {
                            $user->setEmail($email);
                        }
                        $successCount++;
                    } catch (\Exception $e) {
                        $errors[] = "خطا برای $username: " . $e->getMessage();
                    }
                }
            }

            $output->writeln("ایمپورت کامل شد: $successCount کاربر اضافه شدند.");
            if ($errors) {
                $output->writeln("خطاها:");
                foreach ($errors as $error) {
                    $output->writeln($error);
                }
            }
            return 0;
        } catch (\Exception $e) {
            $output->writeln("خطا: " . $e->getMessage());
            return 1;
        }
    }
}

۶.۳.۲ ثبت دستور

فایل: apps/myapp/appinfo/app.php

<?php
namespace OCA\MyApp;

use OCP\AppFramework\App;
use OCA\MyApp\Command\ImportUsers;

class MyApp extends App {
    public function __construct(array $urlParams = []) {
        parent::__construct('myapp', $urlParams);
        $this->getContainer()->getServer()->getCommandBus()->registerCommand(new ImportUsers(
            $this->getContainer()->getServer()->getUserManager()
        ));
    }
}

۶.۳.۳ نمونه فایل اکسل

username password email
user1 pass123 user1@example.com
user2 pass456 user2@example.com

تست دستور:

php occ user:import-excel /path/to/users.xlsx

۶.۴ بهینه‌سازی Active Directory

فایل: server/config/config.php

<?php
$CONFIG = [
    'ldap_cache_ttl' => 7200,
    'ldap_paging_size' => 500,
    'ldap_attribute_mapping' => [
        'uid' => 'sAMAccountName',
        'displayName' => 'displayName',
        'email' => 'mail'
    ],
    'ldap_base' => ['dc=example,dc=com'],
    'ldap_login_filter' => '(&(objectClass=user)(memberOf=cn=NextcloudUsers,ou=Groups,dc=example,dc=com))'
];

تست LDAP:

ldapsearch -x -H ldap://example.com -D "admin@example.com" -W -b "dc=example,dc=com"

۶.۵ تست: اطمینان از مدیریت بی‌نقص

  1. تست عملیات بالک:
   curl -X POST http://localhost:8080/index.php/apps/myapp/api/users/bulk \
       -H "Content-Type: application/json" \
       -d '{"users":["user1","user2"],"quota":"10GB","password":"newpass123"}'
  1. تست مدیریت گروه:
   curl -X POST http://localhost:8080/index.php/apps/myapp/api/groups/developers/level \
       -H "Content-Type: application/json" \
       -d '{"level": 3}'
  1. تست ایمپورت اکسل:
   php occ user:import-excel /path/to/users.xlsx
  1. تست LDAP:
  2. لاگین کاربر LDAP و بررسی همگام‌سازی.
  3. تست عملکرد:
     time php occ ldap:check-user user1

تست‌های لبه:

  • ایمپورت ۱۰۰۰ کاربر.
  • تغییر سهمیه برای کاربران غیرموجود.
  • همگام‌سازی LDAP با گروه‌های پیچیده.

نکات حرفه‌ای

  • امنیت:
  \OCP\Util::addHeader('meta', ['name' => 'require-auth', 'content' => 'admin']);
  • مانیتورینگ: از Prometheus برای رصد LDAP استفاده کنید.
  • مستندسازی: در README.fa.md توضیح دهید.
  • رابط کاربری:
  <template>
      <input v-model="quota" placeholder="سهمیه (مثل 10GB)">
      <button @click="bulkUpdate">اعمال</button>
  </template>
  <script>
  export default {
      data() { return { quota: '', users: ['user1', 'user2'] }; },
      methods: {
          async bulkUpdate() {
              await fetch('/index.php/apps/myapp/api/users/bulk', {
                  method: 'POST',
                  body: JSON.stringify({ users: this.users, quota: this.quota })
              });
          }
      }
  }
  </script>