Merge branch 'trunk'
This commit is contained in:
commit
66c889b02a
8 changed files with 257 additions and 139 deletions
|
|
@ -47,12 +47,3 @@ LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=
|
|||
# GITLAB API
|
||||
GITLAB_URL=
|
||||
GITLAB_TOKEN=
|
||||
|
||||
# SAML IDP
|
||||
## URL list separated by comma
|
||||
SAML_SP_URL_LIST=""
|
||||
## json sp config
|
||||
SAML_SP_CONFIG=''
|
||||
## IDP CERT
|
||||
SAMLIDP_KEY=
|
||||
SAMLIDP_CERT=
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -21,3 +21,4 @@ Homestead.json
|
|||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
storage/samlidp/*
|
||||
|
|
|
|||
42
app/Interfaces/SpsConfigInterface.php
Normal file
42
app/Interfaces/SpsConfigInterface.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Interfaces;
|
||||
|
||||
interface SpsConfigInterface
|
||||
{
|
||||
/**
|
||||
* URL method
|
||||
* Website (SP) url ex: https://le-gaulois-pro.s-web.test
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url(): string;
|
||||
/**
|
||||
* acsBase64 method
|
||||
* Return destination url base64 encoded
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function acsBase64(): string;
|
||||
/**
|
||||
* destination method
|
||||
* Return acs url concatenated with url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function destination(): string;
|
||||
/**
|
||||
* logout method
|
||||
* Return sls url concatenated with url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function logout(): string;
|
||||
/**
|
||||
* certificate method
|
||||
* Return certificate (.pem) file from kebab case of Enum name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function certificate(): string;
|
||||
}
|
||||
52
app/Traits/Enums/SpsConfigTrait.php
Normal file
52
app/Traits/Enums/SpsConfigTrait.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Enums;
|
||||
|
||||
trait SpsConfigTrait
|
||||
{
|
||||
/**
|
||||
* acsBase64 method
|
||||
* Return destination url base64 encoded
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function acsBase64(): string
|
||||
{
|
||||
return base64_encode($this->destination());
|
||||
}
|
||||
/**
|
||||
* destination method
|
||||
* Return acs url concatenated with url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function destination(): string
|
||||
{
|
||||
return $this->url() . "/saml2/support/acs";
|
||||
}
|
||||
/**
|
||||
* logout method
|
||||
* Return sls url concatenated with url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function logout(): string
|
||||
{
|
||||
return $this->url() . "/saml2/support/sls";
|
||||
}
|
||||
/**
|
||||
* certificate method
|
||||
* Return certificate (.pem) file from kebab case of Enum name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function certificate(): string
|
||||
{
|
||||
return 'file://' . storage_path(
|
||||
sprintf(
|
||||
'samlidp/%s.pem',
|
||||
str()->kebab($this->name)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
<?php
|
||||
|
||||
$saml_sp_list = explode(",", env('SAML_SP_URL_LIST', []));
|
||||
foreach ($saml_sp_list as $sp) {
|
||||
$sp_slo_redirects[$sp] = $sp;
|
||||
$config = require_once(storage_path('samlidp/config.php'));
|
||||
|
||||
foreach (SpsEnum::cases() as $sp) {
|
||||
$sp_slo_redirects[$sp->url()] = $sp->url();
|
||||
$sp_configs[$sp->acsBase64()] = [
|
||||
'destination' => $sp->destination(),
|
||||
'logout' => $sp->logout(),
|
||||
'certificate' => $sp->certificate()
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
|
|
@ -55,7 +61,7 @@ return [
|
|||
// 'encrypt_assertion' => false
|
||||
// ].
|
||||
// ],.
|
||||
'sp' => json_decode(env('SAML_SP_CONFIG', "{}"), true),
|
||||
'sp' => $sp_configs,
|
||||
|
||||
// If you need to redirect after SLO depending on SLO initiator
|
||||
// Key is beginning of HTTP_REFERER value from SERVER, value is redirect path.
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ data:
|
|||
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
|
||||
GITLAB_URL: "https://${CI_SERVER_HOST}"
|
||||
GITLAB_TOKEN: "${APP_GITLAB_TOKEN}"
|
||||
SAMLIDP_KEY: "${APP_SAMLIDP_KEY}"
|
||||
SAMLIDP_CERT: "${APP_SAMLIDP_CERT}"
|
||||
SAML_SP_URL_LIST: "${APP_SAML_SP_URL_LIST}"
|
||||
SAML_SP_CONFIG: "${APP_SAML_SP_CONFIG}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use App\Http\Controllers\Bo\SiteController;
|
|||
use App\Http\Controllers\Bo\TicketController;
|
||||
use App\Http\Controllers\Bo\TicketTypeController;
|
||||
use App\Http\Controllers\Bo\UserController;
|
||||
use App\Http\Middleware\SecureHeaders;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
|
@ -23,141 +24,145 @@ Route::middleware('admin-secure')
|
|||
->group(function () {
|
||||
|
||||
Route::namespace('\App\Http\Controllers\Bo')
|
||||
->withoutMiddleware([SecureHeaders::class])
|
||||
->group(function () {
|
||||
Auth::routes(
|
||||
[
|
||||
'login' => true,
|
||||
'logout' => true,
|
||||
'register' => false,
|
||||
'reset' => true,
|
||||
'confirm' => false,
|
||||
'verify' => false
|
||||
]
|
||||
);
|
||||
Auth::routes(
|
||||
[
|
||||
'login' => true,
|
||||
'logout' => true,
|
||||
'register' => false,
|
||||
'reset' => true,
|
||||
'confirm' => false,
|
||||
'verify' => false
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
Route::name('bo.')
|
||||
->group(function () {
|
||||
Route::middleware('auth:backend')
|
||||
->group(function () {
|
||||
// * HOME
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
->group(function () {
|
||||
// * HOME
|
||||
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
|
||||
|
||||
Route::middleware(['can:isAdmin'])
|
||||
->group(function () {
|
||||
// * RESOURCES
|
||||
Route::resource('users', UserController::class)->except('show');
|
||||
Route::resource('informations', InformationController::class)->except('show');
|
||||
Route::resource('ticket_types', TicketTypeController::class)
|
||||
->only(['index', 'edit', 'update'])
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware('htmlsanitize:template')
|
||||
->parameters(['ticket_types' => 'ticket_type']);
|
||||
Route::resource('packages', PackageController::class)->except('show');
|
||||
Route::resource('dutyhours', DutyhourController::class)->except('show');
|
||||
Route::resource('invoices', InvoiceController::class)
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware(['htmlsanitize:comment']);
|
||||
Route::resource('companies', CompanyController::class)->except('show');
|
||||
Route::resource('brands', BrandController::class);
|
||||
Route::resource('brands.credit_accounts', AccountController::class)
|
||||
->only(['index', 'create', 'store'])
|
||||
->parameters(['credit_accounts' => 'account']);
|
||||
Route::resource('brands.credit_accounts.credit_logs', CreditLogController::class)
|
||||
->only(['index', 'create', 'store'])
|
||||
->parameters(['credit_accounts' => 'account', 'credit_logs' => 'credit_log']);
|
||||
Route::resource('labels', LabelController::class)->except('show');
|
||||
Route::middleware(['can:isAdmin'])
|
||||
->group(function () {
|
||||
// * RESOURCES
|
||||
Route::resource('users', UserController::class)->except('show');
|
||||
Route::resource('informations', InformationController::class)->except('show');
|
||||
Route::resource('ticket_types', TicketTypeController::class)
|
||||
->only(['index', 'edit', 'update'])
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware('htmlsanitize:template')
|
||||
->parameters(['ticket_types' => 'ticket_type']);
|
||||
Route::resource('packages', PackageController::class)->except('show');
|
||||
Route::resource('dutyhours', DutyhourController::class)->except('show');
|
||||
Route::resource('invoices', InvoiceController::class)
|
||||
->withoutMiddleware('htmlsanitize')
|
||||
->middleware(['htmlsanitize:comment']);
|
||||
Route::resource('companies', CompanyController::class)->except('show');
|
||||
Route::resource('brands', BrandController::class);
|
||||
Route::resource('brands.credit_accounts', AccountController::class)
|
||||
->only(['index', 'create', 'store'])
|
||||
->parameters(['credit_accounts' => 'account']);
|
||||
Route::resource('brands.credit_accounts.credit_logs', CreditLogController::class)
|
||||
->only(['index', 'create', 'store'])
|
||||
->parameters(['credit_accounts' => 'account', 'credit_logs' => 'credit_log']);
|
||||
Route::resource('labels', LabelController::class)->except('show');
|
||||
|
||||
// * INVOICES
|
||||
Route::get('/invoices/json/paginate', [InvoiceController::class, 'jsonPaginate'])
|
||||
->name('invoices.json-paginate');
|
||||
Route::get('/invoices/{invoice}/download', [InvoiceController::class, 'download'])
|
||||
->name('invoices.download');
|
||||
// * INVOICES
|
||||
Route::get('/invoices/json/paginate', [InvoiceController::class, 'jsonPaginate'])
|
||||
->name('invoices.json-paginate');
|
||||
Route::get('/invoices/{invoice}/download', [InvoiceController::class, 'download'])
|
||||
->name('invoices.download');
|
||||
|
||||
// * PROJECTS
|
||||
Route::resource('projects', ProjectController::class);
|
||||
Route::get('/projects/json/paginate', [ProjectController::class, 'jsonPaginate'])
|
||||
->name('projects.json-paginate');
|
||||
// * PROJECTS
|
||||
Route::resource('projects', ProjectController::class);
|
||||
Route::get('/projects/json/paginate', [ProjectController::class, 'jsonPaginate'])
|
||||
->name('projects.json-paginate');
|
||||
|
||||
// * SITES
|
||||
Route::resource('sites', SiteController::class)->except('index');
|
||||
Route::get('/sites/json/paginate', [SiteController::class, 'jsonPaginate'])
|
||||
->name('sites.json-paginate');
|
||||
// * SITES
|
||||
Route::resource('sites', SiteController::class)->except('index');
|
||||
Route::get('/sites/json/paginate', [SiteController::class, 'jsonPaginate'])
|
||||
->name('sites.json-paginate');
|
||||
|
||||
// * TICKETS
|
||||
Route::get('/tickets/json/paginate', [TicketController::class, 'jsonPaginate'])
|
||||
->name('tickets.json-paginate');
|
||||
Route::post('/ticket/{ticket}/create-issue', [TicketController::class, 'createGitlabIssue'])
|
||||
->middleware('can:createGitlabIssue,ticket')
|
||||
->name('ticket.create-issue');
|
||||
});
|
||||
Route::resource('credit_accounts', AccountController::class)
|
||||
->only(['index'])
|
||||
->parameters(['credit_accounts' => 'account']);
|
||||
Route::resource('credit_accounts.credit_logs', CreditLogController::class)
|
||||
->only(['index'])
|
||||
->parameters(['credit_accounts' => 'account', 'credit_logs' => 'credit_log']);
|
||||
|
||||
// * USERS
|
||||
Route::get('/users/change-password', [UserController::class, 'passwordReset'])
|
||||
->name('users.passwordReset');
|
||||
Route::post('/users/change-password', [UserController::class, 'passwordResetSubmit'])
|
||||
->name('users.passwordResetSubmit');
|
||||
|
||||
// * SITES
|
||||
Route::resource('sites', SiteController::class)->only('index');
|
||||
|
||||
// * TICKETS
|
||||
Route::resource('ticket', TicketController::class)->except(['destroy']);
|
||||
Route::prefix('/ticket')
|
||||
->name('ticket.')
|
||||
->group(function () {
|
||||
// * Estimation
|
||||
Route::name('estimation.')->group(function () {
|
||||
Route::get('/{ticket}/estimate', [EstimationController::class, 'estimate'])
|
||||
->middleware('can:estimate,ticket')
|
||||
->name('estimate');
|
||||
Route::post('/{ticket}/estimate', [EstimationController::class, 'estimateSubmit'])
|
||||
->middleware('can:estimate,ticket')
|
||||
->name('estimateSubmit');
|
||||
Route::post('/{ticket}/estimate/answer', [
|
||||
EstimationController::class, 'estimatePendingSubmit'
|
||||
])
|
||||
->middleware('can:validateEstimate,ticket')
|
||||
->name('estimatePendingSubmit');
|
||||
Route::post('/{ticket}/estimate/cancel', [
|
||||
EstimationController::class,
|
||||
'estimateCancelSubmit'
|
||||
])
|
||||
->middleware('can:cancelEstimate,ticket')
|
||||
->name('estimateCancelSubmit');
|
||||
// * TICKETS
|
||||
Route::get('/tickets/json/paginate', [TicketController::class, 'jsonPaginate'])
|
||||
->name('tickets.json-paginate');
|
||||
Route::post(
|
||||
'/ticket/{ticket}/create-issue',
|
||||
[TicketController::class, 'createGitlabIssue']
|
||||
)
|
||||
->middleware('can:createGitlabIssue,ticket')
|
||||
->name('ticket.create-issue');
|
||||
});
|
||||
Route::resource('credit_accounts', AccountController::class)
|
||||
->only(['index'])
|
||||
->parameters(['credit_accounts' => 'account']);
|
||||
Route::resource('credit_accounts.credit_logs', CreditLogController::class)
|
||||
->only(['index'])
|
||||
->parameters(['credit_accounts' => 'account', 'credit_logs' => 'credit_log']);
|
||||
|
||||
Route::post('/{ticket}/assignTo', [TicketController::class, 'assignTo'])
|
||||
->middleware('can:assignTo,ticket')
|
||||
->name('assignTo');
|
||||
Route::post('/{ticket}/reopen', [TicketController::class, 'reopen'])
|
||||
->middleware('can:reopen,ticket')
|
||||
->name('reopen');
|
||||
Route::post('/{ticket}/status', [TicketController::class, 'changeStatus'])
|
||||
->middleware('can:changeStatus,ticket')
|
||||
->name('changeStatus');
|
||||
Route::post('/{ticket}/subscribe', [TicketController::class, 'subscribe'])
|
||||
->middleware('can:suscribeToTicket,ticket')
|
||||
->name('subscribe');
|
||||
Route::put('/{ticket}/archive', [TicketController::class, 'setToArchive'])
|
||||
->middleware('can:changeStatus,ticket')
|
||||
->name('archive');
|
||||
Route::put('/{ticket}/message/create', [TicketController::class, 'createMessage'])
|
||||
->middleware('can:createMessage,ticket')
|
||||
->name('message.create');
|
||||
Route::put('/{ticket}/message/{message}/update', [
|
||||
TicketController::class,
|
||||
'updateMessage'
|
||||
])->middleware('can:updateMessage,ticket,message')
|
||||
->name('message.update');
|
||||
});
|
||||
});
|
||||
// * USERS
|
||||
Route::get('/users/change-password', [UserController::class, 'passwordReset'])
|
||||
->name('users.passwordReset');
|
||||
Route::post('/users/change-password', [UserController::class, 'passwordResetSubmit'])
|
||||
->name('users.passwordResetSubmit');
|
||||
|
||||
// * SITES
|
||||
Route::resource('sites', SiteController::class)->only('index');
|
||||
|
||||
// * TICKETS
|
||||
Route::resource('ticket', TicketController::class)->except(['destroy']);
|
||||
Route::prefix('/ticket')
|
||||
->name('ticket.')
|
||||
->group(function () {
|
||||
// * Estimation
|
||||
Route::name('estimation.')->group(function () {
|
||||
Route::get('/{ticket}/estimate', [EstimationController::class, 'estimate'])
|
||||
->middleware('can:estimate,ticket')
|
||||
->name('estimate');
|
||||
Route::post('/{ticket}/estimate', [EstimationController::class, 'estimateSubmit'])
|
||||
->middleware('can:estimate,ticket')
|
||||
->name('estimateSubmit');
|
||||
Route::post('/{ticket}/estimate/answer', [
|
||||
EstimationController::class, 'estimatePendingSubmit'
|
||||
])
|
||||
->middleware('can:validateEstimate,ticket')
|
||||
->name('estimatePendingSubmit');
|
||||
Route::post('/{ticket}/estimate/cancel', [
|
||||
EstimationController::class,
|
||||
'estimateCancelSubmit'
|
||||
])
|
||||
->middleware('can:cancelEstimate,ticket')
|
||||
->name('estimateCancelSubmit');
|
||||
});
|
||||
|
||||
Route::post('/{ticket}/assignTo', [TicketController::class, 'assignTo'])
|
||||
->middleware('can:assignTo,ticket')
|
||||
->name('assignTo');
|
||||
Route::post('/{ticket}/reopen', [TicketController::class, 'reopen'])
|
||||
->middleware('can:reopen,ticket')
|
||||
->name('reopen');
|
||||
Route::post('/{ticket}/status', [TicketController::class, 'changeStatus'])
|
||||
->middleware('can:changeStatus,ticket')
|
||||
->name('changeStatus');
|
||||
Route::post('/{ticket}/subscribe', [TicketController::class, 'subscribe'])
|
||||
->middleware('can:suscribeToTicket,ticket')
|
||||
->name('subscribe');
|
||||
Route::put('/{ticket}/archive', [TicketController::class, 'setToArchive'])
|
||||
->middleware('can:changeStatus,ticket')
|
||||
->name('archive');
|
||||
Route::put('/{ticket}/message/create', [TicketController::class, 'createMessage'])
|
||||
->middleware('can:createMessage,ticket')
|
||||
->name('message.create');
|
||||
Route::put('/{ticket}/message/{message}/update', [
|
||||
TicketController::class,
|
||||
'updateMessage'
|
||||
])->middleware('can:updateMessage,ticket,message')
|
||||
->name('message.update');
|
||||
});
|
||||
});
|
||||
|
||||
// * Session Ping
|
||||
Route::get('/ping', function () {
|
||||
|
|
|
|||
25
storage/samlidp/config.php
Normal file
25
storage/samlidp/config.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
use App\Interfaces\SpsConfigInterface;
|
||||
use App\Traits\Enums\SpsConfigTrait;
|
||||
|
||||
// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace
|
||||
enum SpsEnum implements SpsConfigInterface
|
||||
{
|
||||
use SpsConfigTrait;
|
||||
|
||||
case LeGauloisPro;
|
||||
|
||||
/**
|
||||
* URL method
|
||||
* Website url ex: https://le-gaulois-pro.s-web.test
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url(): string
|
||||
{
|
||||
return match ($this) {
|
||||
SpsEnum::LeGauloisPro => 'https://le-gaulois-pro.s-web.test'
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue