uniguide/pportalen-laravel-gw

Pportalen 认证和资源 API 的包装器

1.1.4 2024-05-28 22:03 UTC

This package is auto-updated.

Last update: 2024-09-28 22:36:33 UTC


README

  • 至少 PHP 7.1
  • 至少 Laravel 5.8

安装

  1. 使用 composer 安装 composer require uniguide/pportalen-laravel-gw
  2. 编辑 config\services.php
    'pportalen' => [
        'endpoint' => env('PPORTALEN_ENDPOINT', 'https://api.personal.uniguide.se/v1/'),
        'app_id' => env('PPORTALEN_APP_ID'), // public
        'access_token' => env('PPORTALEN_ACCESS_TOKEN'), // secret
    ]
  1. 将这些添加到 .env
PPORTALEN_APP_ID=XXXXX
PPORTALEN_ACCESS_TOKEN=YYYYY

认证流程

  1. 未认证用户应重定向到 https://personal.uniguide.se/login?app=<PPORTALEN_APP_ID>
  2. 登录成功后,会向 https://<app-callback-url>?tmpToken=<TmpToken> 发送 GET 请求
  3. 回调端点可以在短时间内解析 Gateway::resolveToken('<TmpToken>')

示例实现

<?php

namespace App\Http\Controllers;

use App\Models\User;
use GuzzleHttp\Exception\RequestException;
use Uniguide\Pportalen\Gateway as PPGateway;
use Illuminate\Http\Request;

class PPAuthController
{
    public function __invoke(Request $request)
    {
        try {
            $authenticatedUser = PPGateway::resolveToken($request->get('tmpToken'));
            
            // Active Directory (AD), a security identifier (SID) with format "S-1-5-21-XXXXXXXX-YYYYYYYYYYY-ZZZZZZZ-123"
            $userModel = User::firstOrNew(['ad_sid' => $authenticatedUser->ad_sid]);
            $userModel->name = $authenticatedUser->full_name;
            $userModel->email = $authenticatedUser->work_email;
            // ...
            $userModel->save();
            // Allow user 
            return redirect()->to('admin.dashboard')
           
        } catch (RequestException $exception) {
            // something went wrong, expired token, wrong token, wrong access token etc.
        }
    }
}

同步所有用户

始终保留所有员工副本

实现示例

app\Jobs\SyncUsersJob.php

<?php

namespace App\Jobs;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Uniguide\Pportalen\DataTransferObjects\UserDTO;
use Uniguide\Pportalen\Gateway as PPGateway;

class SyncUsersJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        PPGateway::getUsers()->each(function (UserDTO $DTO) {

            // Active Directory (AD), a security identifier (SID) with format "S-1-5-21-XXXXXXXX-YYYYYYYYYYY-ZZZZZZZ-123"
            $user = User::firstOrNew([
                'ad_sid' => $DTO->ad_sid
            ]);
            // Set fields
            $user->email = $DTO->work_email;
            // Save the user
            $user->save();
            if ($user->wasRecentlyCreated) {
                // User was newely created
            } else {
                // User existed since before
            }
        });
    }
}

``

app\Console\Kernel.php

<?php

namespace App\Console;

use App\Console\Commands\BeaWorkerCommand;
use App\Jobs\SyncUsersJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    //...
    protected function schedule(Schedule $schedule)
    {
        $schedule->job(new SyncUsersJob())->everyFifteenMinutes();
    }
    //...
}

Webhooks

<?php

namespace App\Http\Controllers;

use App\Models\User;
use GuzzleHttp\Exception\RequestException;
use Uniguide\Pportalen\Gateway as PPGateway;
use Illuminate\Http\Request;
use Uniguide\Pportalen\DataTransferObjects\WebhookDTO;

class PPAuthController
{
    public function __invoke(Request $request)
    {
        $webHookDTO = new WebhookDTO($request->all());
        switch($webHookDTO->event_name){
            case "UserCreated":
               /// do stuff
            break;
        }
    }
}

可用事件

enum AppApiDispatchableEvent {

    case UserCreated; // User is created for the first time
    case UserRestored; // Previously missing user has been restored
    case UserMissing; // User is missing, soft deleted.
    case UserRoleChanged; // is_administrator or is_developer changed
    case DepartmentCreated;
    case DepartmentUpdated;
    case DepartmentDeleted;
}

触发完整同步

使用以下事件触发完整同步

use Uniguide\Pportalen\Gateway as PPGateway;

PPGateway::triggerFullSync();

UserCreatedDepartmentCreated 将为每个用户和部门触发。