This commit is contained in:
Alexis Bruneteau 2025-06-04 03:32:12 +02:00
parent dce634e106
commit 0f751754b1
13 changed files with 1139 additions and 179 deletions

40
ansible/deploy_site.yml Normal file
View File

@ -0,0 +1,40 @@
- hosts: web
become: yes
vars:
static_site_local_path: "{{ lookup('env', 'PWD') }}/storage/app/private/portfolios/{{ sitename }}/{{ sitehost }}"
kube_manifest_local_path: "{{ lookup('env', 'PWD') }}/storage/app/kube/{{ sitename }}"
target_path: /var/www/{{ sitename }}/{{ sitehost }}
remote_kube_path: /tmp/kube/{{ sitename }}
tasks:
- name: Ensure target directory exists
file:
path: "{{ target_path }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Copy static site files
copy:
src: "{{ static_site_local_path }}/"
dest: "{{ target_path }}/"
mode: '0644'
- name: Ensure remote kube directory exists
file:
path: "{{ remote_kube_path }}"
state: directory
mode: '0755'
- name: Copy kube manifests to remote server
copy:
src: "{{ kube_manifest_local_path }}/"
dest: "{{ remote_kube_path }}/"
mode: '0644'
- name: Apply Kubernetes manifests
shell: |
kubectl apply -f {{ remote_kube_path }} -n hosting-deploy
args:
executable: /bin/bash

View File

@ -0,0 +1,2 @@
[web]
192.168.1.35 ansible_user=root

View File

@ -0,0 +1,26 @@
<?php
namespace App\Helpers;
use Illuminate\Http\JsonResponse;
class ApiResponse
{
public static function success($data = null, string $message = 'OK', int $status = 200): JsonResponse
{
return response()->json([
'success' => true,
'message' => $message,
'data' => $data,
], $status);
}
public static function error(string $message = 'Error', int $status = 400, $errors = null): JsonResponse
{
return response()->json([
'success' => false,
'message' => $message,
'errors' => $errors,
], $status);
}
}

View File

@ -1,7 +1,5 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -11,44 +9,68 @@ class AuthController extends Controller
{
public function register(Request $request)
{
$fields = $request->validate([
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|confirmed|min:6'
]);
$user = User::create([
'name' => $fields['name'],
'email' => $fields['email'],
'password' => Hash::make($fields['password']),
'password' => 'required|confirmed|min:6',
]);
$token = $user->createToken('api-token')->plainTextToken;
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
$token = $user->createToken('AppToken')->accessToken;;
return response()->json([
'user' => $user,
'token' => $token,
], 201);
'success' => true,
'data' => [
'user' => $user,
'token' => $token,
]
]);
}
public function login(Request $request)
{
$fields = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (!Auth::attempt($credentials)) {
return response()->json(['message' => 'Invalid credentials'], 401);
return response()->json([
'success' => false,
'message' => 'Invalid credentials'
], 401);
}
$user = Auth::user();
$token = $user->createToken('api-token')->plainTextToken;
$token = $user->createToken('AppToken')->accessToken;
return response()->json([
'token' => $token,
'user' => $user,
'success' => true,
'data' => [
'user' => $user,
'token' => $token,
]
]);
}
public function user(Request $request)
{
return response()->json([
'success' => true,
'data' => $request->user()
]);
}
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'success' => true,
'message' => 'Logged out'
]);
}
}

View File

@ -4,7 +4,7 @@ namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
@ -20,4 +20,10 @@ class User extends Authenticatable
'password',
'remember_token',
];
public function portfolios()
{
return $this->hasMany(Portfolio::class);
}
}

View File

@ -2,4 +2,5 @@
return [
App\Providers\AppServiceProvider::class,
App\Providers\AuthProvider::class,
];

View File

@ -11,7 +11,7 @@
"require": {
"php": "^8.2",
"laravel/framework": "^12.0",
"laravel/sanctum": "^4.1",
"laravel/passport": "^13.0",
"laravel/tinker": "^2.10.1"
},
"require-dev": {

1067
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ return [
'guards' => [
'api' => [
'driver' => 'sanctum',
'driver' => 'passport',
'provider' => 'users',
],
],

View File

@ -19,7 +19,7 @@ return [
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:3000')],
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:4200')],
'allowed_origins_patterns' => [],

View File

@ -1,84 +0,0 @@
<?php
use Laravel\Sanctum\Sanctum;
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a backend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:3000,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort(),
env('FRONTEND_URL') ? ','.parse_url(env('FRONTEND_URL'), PHP_URL_HOST) : ''
))),
/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/
'guard' => ['web'],
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. This will override any values set in the token's
| "expires_at" attribute, but first-party sessions are not affected.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Token Prefix
|--------------------------------------------------------------------------
|
| Sanctum can prefix new tokens in order to take advantage of numerous
| security scanning initiatives maintained by open source platforms
| that notify developers if they commit tokens into repositories.
|
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
*/
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],
];

View File

@ -18,7 +18,7 @@ return [
|
*/
'driver' => env('SESSION_DRIVER', 'database'),
'driver' => env('SESSION_DRIVER', 'array'),
/*
|--------------------------------------------------------------------------

View File

@ -3,15 +3,25 @@
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;
use App\Http\Controllers\StaticSiteController;
use App\Http\Controllers\PortfolioController;
Route::post('/auth/register', [AuthController::class, 'register']);
Route::post('/auth/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->get('/me', function (Request $request) {
return $request->user();
});
Route::get('/ping', function () {return 'pongpong';});
Route::get('/pute', function () {return response()->json(['pute' => 'Dimitri']);});
Route::middleware('auth:api')->group(function () {
Route::get('/user', [AuthController::class, 'user']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::apiResource('portfolios', PortfolioController::class);
Route::post('/portfolios/{portfolio}/deploy', [PortfolioController::class, 'deploy']);
Route::post('/portfolios/{portfolio}/upload', [PortfolioController::class, 'upload']);
Route::post('/deploy', [StaticSiteController::class, 'deploy']);
});