summaryrefslogtreecommitdiff
path: root/src/Middleware/ScormPlayerAuthMiddleware.php
blob: 0444f099b0f1f47165ff888e7b8b3eb5fd775a5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php

namespace Lightscale\ScormPlayer\Middleware;

use Peopleaps\Scorm\Model\ScormModel as Scorm;
use Lightscale\ScormPlayer\Models\{
    ScormSco,
    ScormScoTracking,
};

use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

use Illuminate\Support\Facades\Cache;

abstract class ScormPlayerAuthMiddleware
{
    private $cacheTimeout;

    public function __construct()
    {
        $this->cacheTimeout = config('scorm.cache_timeout');
    }

    public function handle(Request $request, Closure $next)
    {
        try {
            $module = $this->findModule($request);
        }
        catch(\Exception $e) {
            return $this->failedResponse();
        }

        $user = $request->user();
        $authorized = Cache::remember(
            'scorm-player-authorize-{$user->id}_{$module->id}',
            $this->cacheTimeout,
            fn() => $this->authorize($request, $module)
        );

        if($authorized) return $next($request);
        else return $this->failedResponse();
    }

    protected function failedResponse() : Response
    {
        return response('Not authorized', 503);
    }

    protected function findModule(Request $request) : Scorm
    {
        $route = $request->route();
        $parameters = $route->parameters();
        $routeName = $route->getName();

        if($routeName === 'scorm-player.serve') {
            $uuid = $route->parameter('uuid');
            return Cache::remember(
                "scrorm-player-uuid-{$uuid}-scorm",
                $this->cacheTimeout,
                fn() => Scorm::where('uuid', $uuid)->firstOrFail()
            );
        }
        else foreach($parameters as $val) {
            if(getType($val) !== 'object') continue;

            if(is_a($val, Scorm::class))
                return $val;
            elseif(is_a($val, ScormSco::class))
                return Cache::remember(
                    "scorm-player-sco-{$val->id}-scorm",
                    $this->cacheTimeout,
                    fn() => $val->scorm
                );
            elseif(is_a($val, ScormScoTracking::class))
                return Cache::remember(
                    "scorm-player-sco-tracking-{$val->id}-scorm",
                    $this->cacheTimeout,
                    fn() => $val->sco->scorm
                );
        }

        throw new \Exception('Failed to find module from route');
    }

    abstract protected function authorize(Request $req, Scorm $module) : bool;
}