diff --git a/docker/webapp/Dockerfile b/docker/webapp/Dockerfile --- a/docker/webapp/Dockerfile +++ b/docker/webapp/Dockerfile @@ -4,7 +4,7 @@ USER root -RUN dnf -y install findutils gnupg2 git rsync procps-ng +RUN dnf -y install findutils gnupg2 git rsync procps-ng php-sodium EXPOSE 8000 diff --git a/src/app/Http/Controllers/API/V4/VPNController.php b/src/app/Http/Controllers/API/V4/VPNController.php new file mode 100644 --- /dev/null +++ b/src/app/Http/Controllers/API/V4/VPNController.php @@ -0,0 +1,48 @@ +guard()->user(); + if (!$user) { + return response()->json(['status' => 'error', 'message' => "Invalid user"], 401); + } + + //TODO look for vpn sku with different access levels? + // Sku::withObjectTenantContext($user)->where('title', 'room')->exists(); + + $tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default())); + //TODO from config + $signingKey = InMemory::base64Encoded( + 'hiG8DlOKvtih6AxlZn5XKImZ06yu8I3mkOzaJrEuW8yAv8Jnkw330uMt8AEqQ5LB' + ); + + // $now = new \DateTimeImmutable(Carbon::now()->instance()); + $token = $tokenBuilder + ->issuedAt(Carbon::now()->toImmutable()) + ->withClaim('entitlement', "gold") + ->getToken(new Hmac\Sha256(), $signingKey); + + return response($token->toString()); + } +} diff --git a/src/composer.json b/src/composer.json --- a/src/composer.json +++ b/src/composer.json @@ -34,7 +34,8 @@ "sabre/vobject": "^4.5", "spatie/laravel-translatable": "^6.3", "spomky-labs/otphp": "~10.0.0", - "stripe/stripe-php": "^10.7" + "stripe/stripe-php": "^10.7", + "lcobucci/jwt": "^4.3" }, "require-dev": { "code-lts/doctum": "^5.5.1", diff --git a/src/routes/api.php b/src/routes/api.php --- a/src/routes/api.php +++ b/src/routes/api.php @@ -188,6 +188,8 @@ Route::post('support/request', [API\V4\SupportController::class, 'request']) ->withoutMiddleware(['auth:api', 'scope:api']) ->middleware(['api']); + + Route::get('vpn/token', [API\V4\VPNController::class, 'token']); } ); diff --git a/src/tests/Feature/Controller/VPNTest.php b/src/tests/Feature/Controller/VPNTest.php new file mode 100644 --- /dev/null +++ b/src/tests/Feature/Controller/VPNTest.php @@ -0,0 +1,66 @@ +getTestUser('john@kolab.org'); + + $response = $this->get("api/v4/vpn/token"); + $response->assertStatus(401); + + $response = $this->actingAs($john)->get("api/v4/vpn/token"); + $response->assertStatus(200); + + $jwt = $response->content(); + + $key = InMemory::base64Encoded( + 'hiG8DlOKvtih6AxlZn5XKImZ06yu8I3mkOzaJrEuW8yAv8Jnkw330uMt8AEqQ5LB' + ); + + $parser = new Parser(new JoseEncoder()); + $token = $parser->parse( + $jwt, + new Constraint\SignedWith(new Sha256(), $key), + ); + + $this->assertSame("gold", $token->claims()->get('entitlement')); + $this->assertSame("2022-02-02T13:00:00+00:00", $token->claims()->get( + RegisteredClaims::ISSUED_AT + )->format(\DateTimeImmutable::RFC3339)); + $this->assertSame(0, Carbon::now()->diffInSeconds(new Carbon($token->claims()->get( + RegisteredClaims::ISSUED_AT + )))); + } +}