diff --git a/app/Enums/CredentialType.php b/app/Enums/CredentialType.php index a49d97c71..70cd8515d 100644 --- a/app/Enums/CredentialType.php +++ b/app/Enums/CredentialType.php @@ -2,6 +2,7 @@ namespace App\Enums; +use App\Traits\HasEnumLongDescription; use BenSampo\Enum\Contracts\LocalizedEnum; use BenSampo\Enum\Enum; @@ -10,6 +11,8 @@ */ final class CredentialType extends Enum implements LocalizedEnum { + use HasEnumLongDescription; + /** * Admin credential. */ diff --git a/app/Events/User/UserInvited.php b/app/Events/User/UserInvited.php index a1f71755f..c585f79aa 100644 --- a/app/Events/User/UserInvited.php +++ b/app/Events/User/UserInvited.php @@ -33,9 +33,9 @@ public function __construct(User $user, ?User $invitedBy = null, ?PublicAdminist /** * Get the user issuing the invitation. * - * @return User the user issuing the invitation + * @return User|string the user issuing the invitation */ - public function getInvitedBy(): User + public function getInvitedBy() { return $this->invitedBy ?? '[API request]'; } diff --git a/app/Http/Controllers/CredentialsController.php b/app/Http/Controllers/CredentialsController.php index 03f5e679f..8948a738f 100644 --- a/app/Http/Controllers/CredentialsController.php +++ b/app/Http/Controllers/CredentialsController.php @@ -2,14 +2,12 @@ namespace App\Http\Controllers; -use App\Enums\UserPermission; +use App\Enums\CredentialType; use App\Exceptions\InvalidCredentialException; use App\Http\Requests\StoreCredentialsRequest; use App\Http\Requests\UpdateCredentialRequest; use App\Models\Credential; -use App\Models\PublicAdministration; -use App\Models\Website; -use App\Traits\HasRoleAwareUrls; +use App\Traits\HasWebsiteDatatable; use App\Traits\SendsResponse; use App\Transformers\CredentialsTransformer; use App\Transformers\WebsitesPermissionsTransformer; @@ -20,7 +18,7 @@ class CredentialsController extends Controller { - use HasRoleAwareUrls; + use HasWebsiteDatatable; use SendsResponse; protected $clientService; @@ -33,11 +31,9 @@ public function __construct() /** * Display the credentials list. * - * @param PublicAdministration $publicAdministration the public administration the credentials belong to - * * @return View the view */ - public function index(Request $request, PublicAdministration $publicAdministration) + public function index(Request $request) { $credentialsDatatable = [ 'columns' => [ @@ -47,17 +43,15 @@ public function index(Request $request, PublicAdministration $publicAdministrati ['data' => 'icons', 'name' => '', 'orderable' => false], ['data' => 'buttons', 'name' => '', 'orderable' => false], ], - 'source' => $this->getRoleAwareUrl('api-credentials.data.json', [], $publicAdministration), + 'source' => route('api-credentials.data.json'), 'caption' => __('elenco delle credenziali presenti su :app', ['app' => config('app.name')]), 'columnsOrder' => [['added_at', 'asc'], ['client_name', 'asc']], ]; - $roleAwareUrls = $this->getRoleAwareUrlArray([ - 'newCredentialUrl' => 'api-credentials.create', - ], [], $publicAdministration); + $newCredentialUrl = route('api-credentials.create'); return view('pages.credentials.index') - ->with($roleAwareUrls) + ->with(compact('newCredentialUrl')) ->with($credentialsDatatable); } @@ -65,24 +59,16 @@ public function index(Request $request, PublicAdministration $publicAdministrati * Show the form for creating a new credential. * * @param Request $request the request - * @param PublicAdministration $publicAdministration the public administration the new credential will belong to * * @return View the view */ - public function create(Request $request, PublicAdministration $publicAdministration): View + public function create(Request $request): View { - $user = $request->user(); - $currentPublicAdministration = $user->can(UserPermission::ACCESS_ADMIN_AREA) - ? $publicAdministration - : current_public_administration(); - - $credentialsStoreUrl = $this->getRoleAwareUrl('api-credentials.store', [], $currentPublicAdministration); + $credentialsStoreUrl = route('api-credentials.store'); - $websitesPermissionsDatatableSource = $this->getRoleAwareUrl( - 'api-credentials.websites.permissions', - ['oldCredentialPermissions' => old('permissions')], - $currentPublicAdministration - ); + $websitesPermissionsDatatableSource = route('api-credentials.websites.permissions', [ + 'oldCredentialPermissions' => old('permissions'), + ]); $websitesPermissionsDatatable = $this->getDatatableWebsitesPermissionsParams($websitesPermissionsDatatableSource); @@ -93,27 +79,20 @@ public function create(Request $request, PublicAdministration $publicAdministrat * Store the credential. * * @param StoreCredentialsRequest $request the request - * @param PublicAdministration $publicAdministration the public administration the new credential will belong to * * @return View|Redirect the view or redirect error */ - public function store(StoreCredentialsRequest $request, PublicAdministration $publicAdministration) + public function store(StoreCredentialsRequest $request) { $validatedData = $request->validated(); $permissions = []; - if (array_key_exists('permissions', $validatedData)) { + if (CredentialType::ANALYTICS === $validatedData['type']) { foreach ($validatedData['permissions'] as $credential => $permission) { array_push($permissions, ['id' => $credential, 'permissions' => implode('', $permission)]); } } - $user = $request->user(); - - $currentPublicAdministration = $user->can(UserPermission::ACCESS_ADMIN_AREA) - ? $publicAdministration - : current_public_administration(); - $clientJSON = $this->clientService ->makeConsumer( $validatedData['credential_name'], @@ -124,7 +103,7 @@ public function store(StoreCredentialsRequest $request, PublicAdministration $pu $client = Credential::create([ 'client_name' => $validatedData['credential_name'], - 'public_administration_id' => $currentPublicAdministration->id, + 'public_administration_id' => current_public_administration()->id, 'consumer_id' => $clientJSON['consumer']['id'], ]); @@ -137,29 +116,21 @@ public function store(StoreCredentialsRequest $request, PublicAdministration $pu * * @param Request $request the request * @param Credential $credential the credential - * @param PublicAdministration $publicAdministration the public administration the credential belongs to * * @return View|Redirect the view or redirect error */ - public function show(Request $request, Credential $credential, PublicAdministration $publicAdministration) + public function show(Request $request, Credential $credential) { - $user = $request->user(); - $currentPublicAdministration = $user->can(UserPermission::ACCESS_ADMIN_AREA) - ? $publicAdministration - : current_public_administration(); - - $roleAwareUrls = $this->getRoleAwareUrlArray([ - 'credentialEditUrl' => 'api-credentials.edit', - 'credentialRegenerate' => 'api-credentials.regenerate', - ], [ - 'credential' => $credential, - ], $currentPublicAdministration); - - $websitesPermissionsDatatableSource = $this->getRoleAwareUrl( - 'api-credentials.websites.permissions', - ['credential' => $credential], - $currentPublicAdministration + $credentialEditUrl = route('api-credentials.edit', + ['credential' => $credential] ); + $credentialRegenerateUrl = route('api-credentials.regenerate', + ['credential' => $credential] + ); + + $websitesPermissionsDatatableSource = route('api-credentials.websites.permissions', [ + 'credential' => $credential, + ]); $websitesPermissionsDatatable = $this->getDatatableWebsitesPermissionsParams($websitesPermissionsDatatableSource, true); @@ -168,10 +139,9 @@ public function show(Request $request, Credential $credential, PublicAdministrat ]; return view('pages.credentials.show') - ->with(compact('credential')) + ->with(compact('credential', 'credentialEditUrl', 'credentialRegenerateUrl')) ->with($credentialData) - ->with($websitesPermissionsDatatable) - ->with($roleAwareUrls); + ->with($websitesPermissionsDatatable); } /** @@ -179,29 +149,16 @@ public function show(Request $request, Credential $credential, PublicAdministrat * * @param Request $request The request * @param Credential $credential The credential - * @param PublicAdministration $publicAdministration the public administration the credential belongs to * * @return View the view */ - public function edit(Request $request, Credential $credential, PublicAdministration $publicAdministration): View + public function edit(Request $request, Credential $credential): View { - $user = $request->user(); - $currentPublicAdministration = $user->can(UserPermission::ACCESS_ADMIN_AREA) - ? $publicAdministration - : current_public_administration(); - - $updateUrl = $this->getRoleAwareUrl('api-credentials.update', [ + $updateUrl = route('api-credentials.update', ['credential' => $credential]); + $websitesPermissionsDatatableSource = route('api-credentials.websites.permissions', [ 'credential' => $credential, - ], $currentPublicAdministration); - - $websitesPermissionsDatatableSource = $this->getRoleAwareUrl( - 'api-credentials.websites.permissions', - [ - 'credential' => $credential, - 'oldCredentialPermissions' => old('permissions'), - ], - $currentPublicAdministration - ); + 'oldCredentialPermissions' => old('permissions'), + ]); $credentialData = [ 'type' => $credential->type, @@ -226,8 +183,8 @@ public function edit(Request $request, Credential $credential, PublicAdministrat public function update(UpdateCredentialRequest $request, Credential $credential): RedirectResponse { $validatedData = $request->validated(); - $permissions = []; + if (array_key_exists('permissions', $validatedData)) { foreach ($validatedData['permissions'] as $credentialId => $permission) { array_push($permissions, ['id' => $credentialId, 'permissions' => implode('', $permission)]); @@ -237,17 +194,21 @@ public function update(UpdateCredentialRequest $request, Credential $credential) $credential->client_name = $validatedData['credential_name']; $credential->save(); - $this->clientService->updateClient($credential->consumer_id, [ - 'username' => $validatedData['credential_name'], - 'custom_id' => json_encode(['type' => $validatedData['type'], 'siteId' => $permissions]), - ]); + if ($credential->type->is(CredentialType::ANALYTICS)) { + $clientData = [ + 'username' => $validatedData['credential_name'], + 'custom_id' => json_encode(['type' => $credential->type->value, 'siteId' => $permissions]), + ]; + $this->clientService->updateClient($credential->consumer_id, $clientData); + } - return redirect()->route('api-credentials.index')->withModal([ + return redirect()->route('api-credentials.index')->withNotification([ 'title' => __('modifica credenziale'), - 'icon' => 'it-check-circle', 'message' => __('La modifica della credenziale :credential è andata a buon fine.', [ 'credential' => '' . $validatedData['credential_name'] . '', ]), + 'status' => 'success', + 'icon' => 'it-check-circle', ]); } @@ -265,7 +226,12 @@ public function delete(Credential $credential) $this->clientService->deleteConsumer($credential->consumer_id); $credential->delete(); - return $this->credentialResponse($credential); + return back()->withNotification([ + 'title' => __('credenziale eliminata'), + 'message' => __('La credenziale :credential è stata eliminata.', ['credential' => '' . e($credential->client_name) . '']), + 'status' => 'success', + 'icon' => 'it-check-circle', + ]); } catch (InvalidCredentialException $exception) { report($exception); $code = $exception->getCode(); @@ -279,20 +245,13 @@ public function delete(Credential $credential) /** * Get the Credentials data. * - * @param PublicAdministration $publicAdministration the Public Administration to filter credentials or null to use current one - * * @throws \Exception if unable to initialize the datatable * * @return mixed the response in JSON format */ - public function dataJson(PublicAdministration $publicAdministration) + public function dataJson() { - $user = auth()->user(); - $currentPublicAdministration = $user->can(UserPermission::ACCESS_ADMIN_AREA) - ? $publicAdministration - : current_public_administration(); - - $data = $currentPublicAdministration->credentials()->get(); + $data = current_public_administration()->credentials()->get(); return DataTables::of($data) ->setTransformer(new CredentialsTransformer()) @@ -309,11 +268,6 @@ public function dataJson(PublicAdministration $publicAdministration) */ public function regenerateCredential(Request $request, Credential $credential): RedirectResponse { - $user = $request->user(); - $currentPublicAdministration = $user->can(UserPermission::ACCESS_ADMIN_AREA) - ? $publicAdministration - : current_public_administration(); - $tokens = $this->clientService->getTokensList(); if ($tokens && array_key_exists('data', $tokens) && is_array($tokens['data'])) { @@ -335,13 +289,13 @@ public function regenerateCredential(Request $request, Credential $credential): /** * Show the oauth credential permissions on websites. * - * @param Website $websites websites associated with the credential + * @param Credential $credential The credential * * @throws \Exception if unable to initialize the datatable * * @return mixed the response in JSON format */ - public function dataWebsitesPermissionsJson() + public function dataWebsitesPermissionsJson(Credential $credential) { $websites = current_public_administration()->websites->all(); @@ -350,47 +304,6 @@ public function dataWebsitesPermissionsJson() ->make(true); } - /** - * Get the datatable parameters for websites permission with specified source. - * - * @param string $source the source paramater for the websites permission datatable - * @param bool $readonly wether the datatable is readonly - * - * @return array the datatable parameters - */ - public function getDatatableWebsitesPermissionsParams(string $source, bool $readonly = false): array - { - return [ - 'datatableOptions' => [ - 'searching' => [ - 'label' => __('cerca tra i siti web'), - ], - 'columnFilters' => [ - 'type' => [ - 'filterLabel' => __('tipologia'), - ], - 'status' => [ - 'filterLabel' => __('stato'), - ], - ], - ], - 'columns' => [ - ['data' => 'website_name', 'name' => __('nome del sito'), 'className' => 'text-wrap'], - ['data' => 'type', 'name' => __('tipologia')], - ['data' => 'status', 'name' => __('stato')], - [ - 'data' => ($readonly ? 'icons' : 'toggles'), - 'name' => __('permessi della credenziale'), - 'orderable' => false, - 'searchable' => false, - ], - ], - 'source' => $source . ($readonly ? '?readOnly' : ''), - 'caption' => __('elenco dei siti web presenti su :app', ['app' => config('app.name')]), - 'columnsOrder' => [['website_name', 'asc']], - ]; - } - /** * Get the datatable parameters for websites permission with specified source. * @@ -407,8 +320,7 @@ protected function getModalCredentialStored(string $clientId, string $clientSecr ? __('La credenziale è stata rigenerata') : __('La credenziale è stata creata'), 'icon' => 'it-check-circle', - 'message' => implode( - "\n", + 'message' => implode("\n", [ __('Adesso puoi utilizzare la tua nuova credenziale e usare le API con il flusso "Client credentials" OAuth2.') . "\n", '' . __('Il tuo client_id è:') . ' ' . $clientId . '', @@ -423,8 +335,8 @@ protected function getModalCredentialStored(string $clientId, string $clientSecr ]), '' . __('Non portà essere più visualizzato dopo la chiusura di questo messaggio.') . '', '
', - '

' . __('In caso di smarrimento o compromissione, può essere rigenerato nella pagina di dettaglio della credenziale.') . '

' . - '', + '

' . __('In caso di smarrimento o compromissione, può essere rigenerato nella pagina di dettaglio della credenziale.') . '

', + '', ]), ]; } diff --git a/app/Http/Controllers/SwaggerController.php b/app/Http/Controllers/SwaggerController.php index 36405e8b3..be305e944 100644 --- a/app/Http/Controllers/SwaggerController.php +++ b/app/Http/Controllers/SwaggerController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Enums\CredentialType; use App\Enums\UserPermission; use App\Models\Credential; use App\Models\PublicAdministration; @@ -9,6 +10,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\View\View; +use Symfony\Component\Yaml\Yaml; class SwaggerController extends Controller { @@ -39,7 +41,7 @@ public function index(Request $request, PublicAdministration $publicAdministrati $credentials = Credential::where('public_administration_id', $currentPublicAdministration->id)->get() ->filter(function ($credential) { - return 'admin' === $credential->type; + return $credential->type->is(CredentialType::ADMIN); }); $hasCredentials = 0 !== count($credentials); @@ -59,21 +61,21 @@ public function index(Request $request, PublicAdministration $publicAdministrati */ public function apiSpecification(): JsonResponse { - $path = resource_path('data/api.json'); + $path = resource_path('data/api.yml'); if (!is_file($path) || !is_readable($path)) { return response() ->json(['error' => 'API configuration file not readable'], 500); } - $data = json_decode(file_get_contents($path)); + $data = Yaml::parseFile($path, Yaml::PARSE_OBJECT_FOR_MAP); $apiUrl = config('kong-service.api_url'); $apiVersion = config('app.api_version'); $basePath = config('kong-service.portal_base_path'); $data->servers = [ [ - 'url' => implode('/', array_filter([ + 'url' => implode('', array_filter([ $apiUrl, $basePath, $apiVersion, @@ -87,7 +89,7 @@ public function apiSpecification(): JsonResponse ->oAuth ->flows ->clientCredentials - ->tokenUrl = $apiUrl . '/portal/oauth2/token'; + ->tokenUrl = $apiUrl . '/oauth2/token'; return response() ->json($data, 200); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 28c062d2f..dda9cac90 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -19,6 +19,7 @@ use App\Models\PublicAdministration; use App\Models\User; use App\Traits\HasRoleAwareUrls; +use App\Traits\HasWebsiteDatatable; use App\Traits\SendsResponse; use App\Transformers\UserArrayTransformer; use App\Transformers\UserTransformer; @@ -40,6 +41,7 @@ class UserController extends Controller { use SendsResponse; use HasRoleAwareUrls; + use HasWebsiteDatatable; /** * Display the users list. @@ -530,42 +532,6 @@ protected function getAllRoles(User $user, PublicAdministration $publicAdministr }); } - /** - * Get the datatable parameters for websites permission with specified source. - * - * @param string $source the source paramater for the websites permission datatable - * @param bool $readonly wether the datatable is readonly - * - * @return array the datatable parameters - */ - protected function getDatatableWebsitesPermissionsParams(string $source, bool $readonly = false): array - { - return [ - 'datatableOptions' => [ - 'searching' => [ - 'label' => __('cerca tra i siti web'), - ], - 'columnFilters' => [ - 'type' => [ - 'filterLabel' => __('tipologia'), - ], - 'status' => [ - 'filterLabel' => __('stato'), - ], - ], - ], - 'columns' => [ - ['data' => 'website_name', 'name' => __('nome del sito'), 'className' => 'text-wrap'], - ['data' => 'type', 'name' => __('tipologia')], - ['data' => 'status', 'name' => __('stato')], - ['data' => ($readonly ? 'icons' : 'toggles'), 'name' => __('permessi sui dati analytics'), 'orderable' => false, 'searchable' => false], - ], - 'source' => $source . ($readonly ? '?readOnly' : ''), - 'caption' => __('elenco dei siti web presenti su :app', ['app' => config('app.name')]), - 'columnsOrder' => [['website_name', 'asc']], - ]; - } - /** * Create a new user. * @@ -755,8 +721,9 @@ protected function manageUserPermissions(array $validatedData, PublicAdministrat */ protected function getUserApiUri(string $fn): string { - return 'to-be-implemented'; - // return config('kong-service.api_url') . - // str_replace('/api/', '/portal/', route('api.users.show', ['fn' => $fn], false)); + $apiUrl = config('kong-service.api_url'); + $apiBasePath = config('kong-service.portal_base_path'); + + return $apiUrl . str_replace('/api/', $apiBasePath, route('api.users.show', ['fn' => $fn], false)); } } diff --git a/app/Http/Controllers/WebsiteController.php b/app/Http/Controllers/WebsiteController.php index 2e6f168e3..c19b08b5a 100644 --- a/app/Http/Controllers/WebsiteController.php +++ b/app/Http/Controllers/WebsiteController.php @@ -211,8 +211,7 @@ public function storeApi(StoreWebsiteRequest $request): JsonResponse */ public function show(Request $request, PublicAdministration $publicAdministration, Website $website) { - $isApiRequest = $request->is('api/*'); - if ($isApiRequest) { + if ($request->is('api/*')) { return $this->websiteResponse($website); } @@ -915,8 +914,9 @@ private function updateWebsiteListCache(Website $website) */ private function getWebsiteAPIUri(Website $website): string { - return 'to-be-implemented'; - // return config('kong-service.api_url') . - // str_replace('/api/', '/portal/', route('api.websites.read', ['website' => $website], false)); + $apiUrl = config('kong-service.api_url'); + $apiBasePath = config('kong-service.portal_base_path'); + + return $apiUrl . str_replace('/api/', $apiBasePath, route('api.websites.read', ['website' => $website], false)); } } diff --git a/app/Http/Middleware/AuthenticateApi.php b/app/Http/Middleware/AuthenticateApi.php index 7d4c23b2a..ac6370c76 100644 --- a/app/Http/Middleware/AuthenticateApi.php +++ b/app/Http/Middleware/AuthenticateApi.php @@ -2,6 +2,7 @@ namespace App\Http\Middleware; +use App\Enums\CredentialType; use App\Models\Credential; use App\Models\User; use App\Models\Website; @@ -36,7 +37,7 @@ public function handle($request, Closure $next) $credentialType = $customId->type; } - if ('admin' !== $credentialType) { + if (CredentialType::ADMIN !== $credentialType) { return response()->json([ 'error' => 'forbidden', 'error_description' => 'Access to the requested resource is forbidden', diff --git a/app/Http/Requests/StoreCredentialsRequest.php b/app/Http/Requests/StoreCredentialsRequest.php index f82d94ec4..f45308a85 100644 --- a/app/Http/Requests/StoreCredentialsRequest.php +++ b/app/Http/Requests/StoreCredentialsRequest.php @@ -32,7 +32,10 @@ public function rules(): array { return [ 'credential_name' => 'required|unique:credentials,client_name|min:3|max:255', - 'type' => 'required', + 'type' => [ + 'required', + Rule::in([CredentialType::ADMIN, CredentialType::ANALYTICS]), + ], 'permissions' => 'required_if:type,' . CredentialType::ANALYTICS . '|array', 'permissions.*' => 'array', 'permissions.*.*' => Rule::in([CredentialPermission::WRITE, CredentialPermission::READ]), diff --git a/app/Http/Requests/UpdateCredentialRequest.php b/app/Http/Requests/UpdateCredentialRequest.php index 0544b1d47..5edc4e61c 100644 --- a/app/Http/Requests/UpdateCredentialRequest.php +++ b/app/Http/Requests/UpdateCredentialRequest.php @@ -29,6 +29,7 @@ public function rules(): array $rules = parent::rules(); $credential = $this->route('credential'); + unset($rules['type']); $rules['credential_name'] = [ 'required', 'min:3', diff --git a/app/Listeners/UserEventsSubscriber.php b/app/Listeners/UserEventsSubscriber.php index cad5a37a6..158cebd8a 100644 --- a/app/Listeners/UserEventsSubscriber.php +++ b/app/Listeners/UserEventsSubscriber.php @@ -83,7 +83,7 @@ public function onInvited(UserInvited $event): void $publicAdministration->sendUserInvitedNotificationToAdministrators($user); } logger()->notice( - 'New user invited: ' . $user->uuid . ' by ' . $invitedBy->uuid, + 'New user invited: ' . $user->uuid . ' by ' . (($invitedBy->uuid ?? false) ? $invitedBy->uuid : $invitedBy), $context ); } diff --git a/app/Models/Credential.php b/app/Models/Credential.php index 624d79706..eb6eb2d76 100644 --- a/app/Models/Credential.php +++ b/app/Models/Credential.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Enums\CredentialType; use BenSampo\Enum\Traits\CastsEnums; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -16,6 +17,15 @@ class Credential extends Model 'consumer_id', ]; + /** + * The attributes that should be cast to enums classes. + * + * @var array enum casted attributes + */ + protected $enumCasts = [ + 'type' => CredentialType::class, + ]; + /** * Get the route key for the model. * diff --git a/app/Traits/HasWebsiteDatatable.php b/app/Traits/HasWebsiteDatatable.php new file mode 100644 index 000000000..d53bf92a1 --- /dev/null +++ b/app/Traits/HasWebsiteDatatable.php @@ -0,0 +1,47 @@ + [ + 'searching' => [ + 'label' => __('cerca tra i siti web'), + ], + 'columnFilters' => [ + 'type' => [ + 'filterLabel' => __('tipologia'), + ], + 'status' => [ + 'filterLabel' => __('stato'), + ], + ], + ], + 'columns' => [ + ['data' => 'website_name', 'name' => __('nome del sito'), 'className' => 'text-wrap'], + ['data' => 'type', 'name' => __('tipologia')], + ['data' => 'status', 'name' => __('stato')], + [ + 'data' => ($readonly ? 'icons' : 'toggles'), + 'name' => __('permessi sul sito web'), + 'orderable' => false, + 'searchable' => false, + ], + ], + 'source' => $source . ($readonly ? '?readOnly' : ''), + 'caption' => __('elenco dei siti web presenti su :app', ['app' => config('app.name')]), + 'columnsOrder' => [['website_name', 'asc']], + ]; + } +} diff --git a/app/Traits/SendsResponse.php b/app/Traits/SendsResponse.php index ced0d4057..2489b5e7a 100644 --- a/app/Traits/SendsResponse.php +++ b/app/Traits/SendsResponse.php @@ -112,6 +112,7 @@ protected function websiteResponse(Website $website, ?array $notification = [], $jsonResponse['status'] = $website->status->key; $jsonResponse['status_description'] = $website->status->description; $jsonResponse['trashed'] = $website->trashed(); + unset($jsonResponse['analyticsId']); } } @@ -178,30 +179,6 @@ protected function notModifiedResponse(?array $headers = []) ]); } - /** - * Returns a success response for the specified credential. - * - * @param Credential $credential the credential - * - * @return JsonResponse|RedirectResponse the response in json or http redirect format - */ - protected function credentialResponse(Credential $credential) - { - return request()->expectsJson() - ? response()->json([ - 'result' => 'ok', - 'id' => $credential->consumer_id, - 'credential_name' => e($credential->client_name), - 'status' => 200, - ]) - : back()->withNotification([ - 'title' => __('credenziale modificata'), - 'message' => __('Il sito web :website è stato eliminato.', ['website' => '' . e($credential->client_name) . '']), - 'status' => 'info', - 'icon' => 'it-info-circle', - ]); - } - /** * Returns an error response with the specified parameters. * diff --git a/app/Transformers/CredentialsTransformer.php b/app/Transformers/CredentialsTransformer.php index 54f245c03..c2abecc12 100644 --- a/app/Transformers/CredentialsTransformer.php +++ b/app/Transformers/CredentialsTransformer.php @@ -2,7 +2,6 @@ namespace App\Transformers; -use App\Enums\CredentialType; use App\Enums\UserPermission; use App\Models\Credential; use League\Fractal\TransformerAbstract; @@ -32,7 +31,7 @@ public function transform(Credential $credential): array ]), 'raw' => e($credential->client_name), ], - 'type' => CredentialType::getDescription($credential->type), + 'type' => $credential->type->description, 'added_at' => $credential->created_at->format('d/m/Y'), 'icons' => [], 'buttons' => [], diff --git a/app/Transformers/WebsiteArrayTransformer.php b/app/Transformers/WebsiteArrayTransformer.php index e0329e35f..983c933fe 100644 --- a/app/Transformers/WebsiteArrayTransformer.php +++ b/app/Transformers/WebsiteArrayTransformer.php @@ -38,6 +38,7 @@ public function transform(Website $website): array return [ 'name' => $website->name, 'url' => $website->url, + 'analyticsId' => $website->analytics_id, 'slug' => $website->slug, 'status' => WebsiteStatus::fromValue($website->status)->description, 'type' => WebsiteType::fromValue($website->type)->description, diff --git a/app/Transformers/WebsitesPermissionsTransformer.php b/app/Transformers/WebsitesPermissionsTransformer.php index 015ba4937..82c849738 100644 --- a/app/Transformers/WebsitesPermissionsTransformer.php +++ b/app/Transformers/WebsitesPermissionsTransformer.php @@ -146,6 +146,6 @@ protected function hasCredentialPermission(int $websiteId, string $permissionTyp $websitePermissions = $credentialPermissions[$websitePermissionIndex]; - return array_key_exists('permission', $websitePermissions) && str_contains($websitePermissions['permission'], $permissionType); + return array_key_exists('permissions', $websitePermissions) && str_contains($websitePermissions['permissions'], $permissionType); } } diff --git a/containers/docker-compose.yml b/containers/docker-compose.yml index 49c12b8ec..1eef54fbc 100644 --- a/containers/docker-compose.yml +++ b/containers/docker-compose.yml @@ -288,6 +288,8 @@ services: context: ./kong args: - KONG_VERSION=${KONG_VERSION} + - KONG_API_PORTAL_BASE_PATH=${KONG_API_PORTAL_BASE_PATH} + - KONG_API_MATOMO_BASE_PATH=${KONG_API_MATOMO_BASE_PATH} depends_on: - postgres environment: diff --git a/containers/kong/kong-setup.sh b/containers/kong/kong-setup.sh index fa6c4c3e4..546b57b56 100644 --- a/containers/kong/kong-setup.sh +++ b/containers/kong/kong-setup.sh @@ -11,9 +11,9 @@ if ! curl -s http://localhost:8001/services | grep -q "nginx"; then curl --output /dev/null --silent -X POST http://localhost:8001/plugins/ --data "name=cors&config.origins=https://localhost" curl --output /dev/null --silent -X POST http://localhost:8001/plugins/ --data "name=oauth2&config.enable_client_credentials=true&config.global_credentials=true&config.accept_http_if_already_terminated=true" curl --output /dev/null --silent -X POST http://localhost:8001/services --data "name=portal&url=https://nginx/api" - curl --output /dev/null --silent -X POST http://localhost:8001/services/portal/routes --data "paths[]=/@KONG_API_PORTAL_BASE_PATH@&name=portal" + curl --output /dev/null --silent -X POST http://localhost:8001/services/portal/routes --data "paths[]=@KONG_API_PORTAL_BASE_PATH@&name=portal" curl --output /dev/null --silent -X POST http://localhost:8001/services --data "name=matomo&url=http://express:7080" - curl --output /dev/null --silent -X POST http://localhost:8001/services/matomo/routes --data "paths[]=/@KONG_API_MATOMO_BASE_PATH@&name=matomo" + curl --output /dev/null --silent -X POST http://localhost:8001/services/matomo/routes --data "paths[]=@KONG_API_MATOMO_BASE_PATH@&name=matomo" fi echo "Kong plugins and routes are ready" diff --git a/env/build.properties.example b/env/build.properties.example index 45d0ccac5..9b6904293 100644 --- a/env/build.properties.example +++ b/env/build.properties.example @@ -327,8 +327,8 @@ XDEBUG_REMOTE_HOST=host.docker.internal KONG_VERSION=2.2.0 KONG_ADMIN_API_URL=http://kong:8001 KONG_API_URL=http://kong:8000 -KONG_API_PORTAL_BASE_PATH=portal -KONG_API_MATOMO_BASE_PATH=matomo +KONG_API_PORTAL_BASE_PATH=/ +KONG_API_MATOMO_BASE_PATH=/matomo # Postgres for Kong # ----------------- diff --git a/env/env-dusk.template b/env/env-dusk.template index a539256d7..7c0c94d62 100644 --- a/env/env-dusk.template +++ b/env/env-dusk.template @@ -94,6 +94,10 @@ ANALYTICS_WIDGETS_BASE_URL=@ANALYTICS_WIDGETS_BASE_URL@ ANALYTICS_PUBLIC_DASHBOARD_ID= ANALYTICS_CRON_ARCHIVING_ENABLED=@MATOMO_CRON_ARCHIVING_ENABLED@ +KONG_ADMIN_API_URL=@KONG_ADMIN_API_URL@ +KONG_API_URL=@KONG_API_URL@ +KONG_API_PORTAL_BASE_PATH=@KONG_API_PORTAL_BASE_PATH@ + SDG_API_PUBLIC_URL=@SDG_API_PUBLIC_URL@ SDG_API_SSL_VERIFY=@SDG_API_SSL_VERIFY@ SDG_API_KEY=@SDG_API_KEY@ @@ -108,14 +112,3 @@ SDG_URL_KEY_JSON=@SDG_URL_KEY_JSON@ TRACKING_MATOMO_ID=@TRACKING_MATOMO_ID@ TRACKING_GA_ID=@TRACKING_GA_ID@ TRACKING_HOTJAR_ID=@TRACKING_HOTJAR_ID@ - -# Kong Service -KONG_VERSION=@KONG_VERSION@ -KONG_ADMIN_API_URL=@KONG_ADMIN_API_URL@ -KONG_API_URL=@KONG_API_URL@ -KONG_API_PORTAL_BASE_PATH=@KONG_API_PORTAL_BASE_PATH@ - -# Postgres Kong -POSTGRES_PASSWORD=@POSTGRES_PASSWORD@ -POSTGRES_USER=@POSTGRES_USER@ -POSTGRES_DATABASE=@POSTGRES_DATABASE@ diff --git a/env/env-laravel.template b/env/env-laravel.template index 29307066e..5a56d5369 100644 --- a/env/env-laravel.template +++ b/env/env-laravel.template @@ -122,6 +122,10 @@ ANALYTICS_WIDGETS_BASE_URL=@ANALYTICS_WIDGETS_BASE_URL@ ANALYTICS_PUBLIC_DASHBOARD_ID=@ANALYTICS_PUBLIC_DASHBOARD_ID@ ANALYTICS_CRON_ARCHIVING_ENABLED=@MATOMO_CRON_ARCHIVING_ENABLED@ +KONG_ADMIN_API_URL=@KONG_ADMIN_API_URL@ +KONG_API_URL=@KONG_API_URL@ +KONG_API_PORTAL_BASE_PATH=@KONG_API_PORTAL_BASE_PATH@ + SDG_API_PUBLIC_URL=@SDG_API_PUBLIC_URL@ SDG_API_SSL_VERIFY=@SDG_API_SSL_VERIFY@ SDG_API_KEY=@SDG_API_KEY@ @@ -144,14 +148,3 @@ ELASTICSEARCH_SEARCH_TEMPLATE_NAME=@ELASTICSEARCH_SEARCH_TEMPLATE_NAME@ TRACKING_MATOMO_ID=@TRACKING_MATOMO_ID@ TRACKING_GA_ID=@TRACKING_GA_ID@ TRACKING_HOTJAR_ID=@TRACKING_HOTJAR_ID@ - -# Kong Service -KONG_VERSION=@KONG_VERSION@ -KONG_ADMIN_API_URL=@KONG_ADMIN_API_URL@ -KONG_API_URL=@KONG_API_URL@ -KONG_API_PORTAL_BASE_PATH=@KONG_API_PORTAL_BASE_PATH@ - -# Postgres Kong -POSTGRES_PASSWORD=@POSTGRES_PASSWORD@ -POSTGRES_USER=@POSTGRES_USER@ -POSTGRES_DATABASE=@POSTGRES_DATABASE@ diff --git a/resources/data/api.json b/resources/data/api.json deleted file mode 100644 index ef0d7d489..000000000 --- a/resources/data/api.json +++ /dev/null @@ -1,1629 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "version": "1.0.0", - "title": "Web Analytics Italia API", - "description": "Questa interfaccia API si riferisce alle operazioni che le Pubbliche Amministrazioni possono eseguire in interoperabilità per gestire utenti e siti di WAI.", - "contact": { - "name": "AGID - Web Analytics Italia", - "url": "https://webanalytics.italia.it/contacts", - "email": "wai@agid.gov.it" - } - }, - "servers": [], - "paths": { - "/users": { - "post": { - "tags": ["Utenti"], - "summary": "Crea un nuovo utente", - "operationId": "addUser", - "requestBody": { - "description": "Dati dell'utente da creare", - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/User" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "responses": { - "201": { - "description": "Dati dell'utente", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del nuovo utente" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserInfo" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - }, - "examples": { - "Bad Request": { - "$ref": "#/components/examples/Error400" - } - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "422": { - "description": "Dati inviati incompleti o invalidi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error422User" - }, - "examples": { - "Unprocessable Entity (User)": { - "$ref": "#/components/examples/Error422User" - } - } - } - } - } - } - }, - "get": { - "tags": ["Utenti"], - "summary": "Fornisce l'elenco degli utenti", - "operationId": "getUsers", - "responses": { - "200": { - "description": "Elenco degli utenti", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/UserInfo" - } - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - } - } - } - }, - "/users/{fn}": { - "parameters": [ - { "$ref": "#/components/parameters/FiscalNumber" } - ], - "get": { - "tags": ["Utenti"], - "summary": "Fornisce i dati dell'utente specificato", - "operationId": "getUser", - "responses": { - "200": { - "description": "Dati dell'utente", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserInfo" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - }, - "put": { - "tags": ["Utenti"], - "summary": "Modifica i dati dell'utente specificato", - "operationId": "updateUser", - "requestBody": { - "description": "Dati dell'utente da modificare", - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserInfo" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "responses": { - "200": { - "description": "Dati dell'utente", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserInfo" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - }, - "422": { - "description": "Dati inviati incompleti o invalidi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error422User" - }, - "examples": { - "Unprocessable Entity (User)": { - "$ref": "#/components/examples/Error422User" - } - } - } - } - } - } - } - }, - "/users/{fn}/suspend": { - "parameters": [ - { "$ref": "#/components/parameters/FiscalNumber" } - ], - "patch": { - "tags": ["Utenti"], - "summary": "Sospende l'utente specificato", - "operationId": "suspendUser", - "responses": { - "200": { - "description": "Dati dell'utente", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserInfo" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "303": { - "description": "Utente già sospeso", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del sito web" - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - } - }, - "/users/{fn}/reactivate": { - "parameters": [ - { "$ref": "#/components/parameters/FiscalNumber" } - ], - "patch": { - "tags": ["Utenti"], - "summary": "Riattiva l'utente specificato", - "operationId": "reactivateUser", - "responses": { - "200": { - "description": "Dati dell'utente", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserInfo" - }, - "examples": { - "userExample": { - "$ref": "#/components/examples/User" - } - } - } - } - }, - "303": { - "description": "Utente già attivo", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del sito web" - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - } - }, - "/websites": { - "post": { - "tags": ["Siti web"], - "summary": "Crea un nuovo sito web", - "operationId": "addWebsite", - "requestBody": { - "description": "Dati del sito web da creare", - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Website" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/Website" - } - } - } - } - }, - "responses": { - "201": { - "description": "Dati del sito web", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del nuovo sito web" - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebsiteInfo" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "422": { - "description": "Dati inviati incompleti o invalidi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error422Website" - }, - "examples": { - "Unprocessable Entity (Website)": { - "$ref": "#/components/examples/Error422Website" - } - } - } - } - } - } - }, - "get": { - "tags": ["Siti web"], - "summary": "Fornisce l'elenco dei siti web", - "operationId": "getWebsites", - "responses": { - "200": { - "description": "Elenco dei siti web", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WebsiteInfo" - } - }, - "examples": { - "WebsiteInfoExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - } - } - } - }, - "/websites/{website}": { - "parameters": [{ "$ref": "#/components/parameters/WebsiteSlug" }], - "get": { - "tags": ["Siti web"], - "summary": "Fornisce i dati del sito web specificato", - "operationId": "getWebsite", - "responses": { - "200": { - "description": "Dati del sito web", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebsiteInfo" - }, - "examples": { - "WebsiteInfoExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - }, - "put": { - "tags": ["Siti web"], - "summary": "Modifica un sito web specificato", - "operationId": "updateWebsite", - "requestBody": { - "description": "Dati del sito web da modificare", - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Website" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/Website" - } - } - } - } - }, - "responses": { - "200": { - "description": "Dati del sito web", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebsiteInfo" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - }, - "422": { - "description": "Dati inviati incompleti o invalidi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error422Website" - }, - "examples": { - "Unprocessable Entity (Website)": { - "$ref": "#/components/examples/Error422Website" - } - } - } - } - } - } - } - }, - "/websites/{website}/archive": { - "parameters": [{ "$ref": "#/components/parameters/WebsiteSlug" }], - "patch": { - "tags": ["Siti web"], - "summary": "Archivia il sito web specificato", - "operationId": "archiveWebsite", - "responses": { - "200": { - "description": "Dati del sito web", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebsiteInfo" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "303": { - "description": "Sito web già attivo", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del sito web" - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - } - }, - "/websites/{website}/unarchive": { - "parameters": [{ "$ref": "#/components/parameters/WebsiteSlug" }], - "patch": { - "tags": ["Siti web"], - "summary": "Riattiva il sito web specificato", - "operationId": "unarchiveWebsite", - "responses": { - "200": { - "description": "Dati del sito web", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebsiteInfo" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "303": { - "description": "Sito web già attivo", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del sito web" - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - } - }, - "/websites/{website}/check": { - "parameters": [{ "$ref": "#/components/parameters/WebsiteSlug" }], - "get": { - "tags": ["Siti web"], - "summary": "Verifica l'attivazione del sito web specificato", - "operationId": "checkWebsite", - "responses": { - "200": { - "description": "Sito web attivato", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WebsiteInfo" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/WebsiteInfo" - } - } - } - } - }, - "303": { - "description": "Sito web già attivo", - "headers": { - "Location": { - "schema": { - "type": "string", - "format": "uri" - }, - "description": "Uri del sito web" - } - } - }, - "400": { - "description": "Richiesta erronea", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error400" - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - } - }, - "/websites/{website}/js-snippet": { - "parameters": [{ "$ref": "#/components/parameters/WebsiteSlug" }], - "get": { - "tags": ["Siti web"], - "summary": "Fornisce lo snippet javascript del sito web specificato", - "operationId": "websiteJsSnippet", - "responses": { - "200": { - "description": "Snippet javascript del sito web specificato", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JsSnippet" - }, - "examples": { - "WebsiteExample": { - "$ref": "#/components/examples/JsSnippet" - } - } - } - } - }, - "401": { - "description": "Dati di autorizzazione non validi", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error401" - }, - "examples": { - "Unauthorized": { - "$ref": "#/components/examples/Error401" - } - } - } - } - }, - "403": { - "description": "Permessi non sufficienti per accedere alla risorsa", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error403" - }, - "examples": { - "Forbidden": { - "$ref": "#/components/examples/Error403" - } - } - } - } - }, - "404": { - "description": "Risorsa non trovata", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error404" - } - } - } - } - } - } - } - }, - "components": { - "parameters": { - "WebsiteSlug": { - "in": "path", - "required": true, - "name": "website", - "description": "Slug del sito web", - "schema": { - "$ref": "#/components/schemas/WebsiteSlug" - } - }, - "FiscalNumber": { - "in": "path", - "required": true, - "name": "fn", - "description": "Codice fiscale dell'utente", - "schema": { - "$ref": "#/components/schemas/FiscalNumber" - } - } - }, - "schemas": { - "User": { - "allOf": [ - { - "$ref": "#/components/schemas/UserBase" - }, - { - "properties": { - "is_admin": { - "type": "boolean", - "description": "Specifica se il nuovo utente dovrà essere un admin (se omesso vale `falso`)" - } - } - } - ] - }, - "UserInfo": { - "allOf": [ - { - "required": ["first_name", "family_name", "role"], - "properties": { - "first_name": { - "type": "string", - "description": "Nome dell'utente" - }, - "family_name": { - "type": "string", - "description": "Cognome dell'utente" - } - } - }, - { - "$ref": "#/components/schemas/UserBase" - }, - { - "properties": { - "role": { - "$ref": "#/components/schemas/UserRole" - } - } - } - ] - }, - "UserBase": { - "type": "object", - "required": ["email", "fiscal_number", "permissions"], - "properties": { - "email": { - "type": "string", - "pattern": "email", - "description": "Indirizzo email dell'utente" - }, - "fiscal_number": { - "$ref": "#/components/schemas/FiscalNumber" - }, - "permissions": { - "$ref": "#/components/schemas/WebsitePermissions" - } - } - }, - "FiscalNumber": { - "type": "string", - "pattern": "^[A-Z]{6}\\d{2}[A-Z]\\d{2}[A-Z]\\d{3}[A-Z]$", - "description": "Codice fiscale dell'utente" - }, - "UserRole": { - "type": "string", - "description": "Ruolo dell'utente", - "enum": [ - "administrator", - "delegate" - ] - }, - "WebsitePermissions": { - "type": "object", - "description": "Elenco dei permessi per ciascun sito web. La chiave della coppia sito/permessi deve essere uno slug di un sito web esistente.", - "propertyNames": { - "$ref": "#/components/schemas/WebsiteSlug" - }, - "additionalProperties": { - "type": "array", - "description": "Elenco dei permessi dell'utente per il sito web", - "items": { - "type": "string", - "enum": [ - "manage-analytics", - "read-analytics" - ] - } - } - }, - "WebsiteInfo": { - "allOf": [ - { - "required": ["slug", "status"], - "properties": { - "slug": { - "$ref": "#/components/schemas/WebsiteSlug" - }, - "status": { - "$ref": "#/components/schemas/WebsiteStatus" - } - } - }, - { - "$ref": "#/components/schemas/Website" - } - ] - }, - "Website": { - "type": "object", - "required": ["website_name", "url", "type", "permissions"], - "description": "Sito web", - "properties": { - "website_name": { - "description": "Nome del sito web", - "type": "string", - "pattern": "^(?!\\s).+$" - }, - "url": { - "description": "Url del sito web", - "type": "string", - "format": "uri" - }, - "type": { - "$ref": "#/components/schemas/WebsiteType" - }, - "permissions": { - "$ref": "#/components/schemas/UserPermissions" - } - } - }, - "WebsiteSlug": { - "type": "string", - "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$", - "description": "Slug del sito web" - }, - "WebsiteType": { - "type": "string", - "description": "Tipologia del sito web", - "enum": [ - "institutional website", - "informational or thematic website", - "services website", - "mobile application" - ] - }, - "WebsiteStatus": { - "type": "string", - "description": "Stato del sito", - "enum": ["pending", "active", "archived"] - }, - "UserPermissions": { - "type": "object", - "description": "Elenco dei permessi di ciascun utente. La chiave della coppia utente/permessi deve essere il codice fiscale di un utente esistente.", - "propertyNames": { - "$ref": "#/components/schemas/FiscalNumber" - }, - "additionalProperties": { - "type": "array", - "description": "Elenco dei permessi dell'utente sul sito web", - "items": { - "type": "string", - "enum": [ - "manage-analytics", - "read-analytics" - ] - } - } - }, - "JsSnippet": { - "type": "object", - "required": ["slug", "javascriptSnippet"], - "description": "Informazioni per il tracciamento del sito web", - "properties": { - "slug": { - "$ref": "#/components/schemas/WebsiteSlug" - }, - "javascriptSnippet": { - "description": "Codice javascript per il tracciamento delle visite", - "type": "string" - } - } - }, - "Error400": { - "type": "object", - "required": ["error_description", "error"], - "properties": { - "error_description": { - "type": "string" - }, - "error": { - "type": "string" - }, - "error_code": { - "type": "string" - } - } - }, - "Error401": { - "type": "object", - "required": ["error_description", "error"], - "properties": { - "error_description": { - "type": "string" - }, - "error": { - "type": "string" - } - } - }, - "Error403": { - "type": "object", - "required": ["error_description", "error"], - "properties": { - "error_description": { - "type": "string" - }, - "error": { - "type": "number" - } - } - }, - "Error404": { - "type": "object", - "required": ["error_description", "error"], - "properties": { - "error_description": { - "type": "string" - }, - "error": { - "type": "string" - } - } - }, - "Error422": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - }, - "Error422User": { - "allOf": [ - { - "$ref": "#/components/schemas/Error422" - }, - { - "properties": { - "errors": { - "type": "object", - "properties": { - "email": { - "type": "array", - "items": { - "type": "string" - } - }, - "fiscal_number": { - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - } - } - ] - }, - "Error422Website": { - "allOf": [ - { - "$ref": "#/components/schemas/Error422" - }, - { - "properties": { - "errors": { - "type": "object", - "properties": { - "name": { - "type": "array", - "items": { - "type": "string" - } - }, - "url": { - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - } - } - ] - } - }, - "examples": { - "User": { - "summary": "User", - "value": { - "email": "name@email.com", - "fiscal_number": "VMGHNY33L47D490P", - "permissions": { - "website-slug": ["manage-analytics"] - } - } - }, - "Website": { - "summary": "Website", - "value": { - "website_name": "Nome Sito", - "url": "https://url-sito-web.it/", - "type": 1, - "permissions": { - "VMGHNY33L47D490P": ["read-analytics"] - } - } - }, - "WebsiteInfo": { - "summary": "Website", - "value": { - "website_name": "Agenzia per L'Italia Digitale", - "url": "www.agid.gov.it", - "slug": "wwwagidgovit", - "status": "active", - "type": "institutional website" - } - }, - "JsSnippet": { - "summary": "Javascript Snippet for matomo", - "value": { - "slug": "wwwagidgovit", - "javascriptSnippet": "\n\n" - } - }, - "Error400": { - "summary": "Bad Request", - "value": { - "error_description": "error", - "error": "bad_request", - "error_code": "1" - } - }, - "Error401": { - "summary": "Unauthorized", - "value": { - "error_description": "The access token is invalid or has expired", - "error": "invalid_token" - } - }, - "Error403": { - "summary": "Forbidden", - "value": { - "error_description": "Access to the requested resource is forbidden", - "error": "forbidden" - } - }, - "Error404": { - "summary": "Not Found", - "value": { - "error_description": "The requested resource cannot be found on this server", - "error": "not_found" - } - }, - "Error422": { - "summary": "Unprocessable Entity", - "value": { - "message": "The given data was invalid." - } - }, - "Error422User": { - "summary": "Unprocessable Entity (User)", - "value": { - "allOf": [ - { - "$ref": "#/components/examples/Error422" - }, - { - "errors": { - "email": [ - "The email address field is required." - ], - "fiscal_number": [ - "The fiscal code field is required." - ], - "permissions": [ - "The permissions field is required." - ] - } - } - ] - } - }, - "Error422Website": { - "summary": "Unprocessable Entity (Website)", - "value": { - "allOf": [ - { - "$ref": "#/components/examples/Error422" - }, - { - "errors": { - "website_name": [ - "The website name field is required." - ], - "url": ["The URL field is required."], - "type": ["The type field is required."] - } - } - ] - } - } - }, - "securitySchemes": { - "oAuth": { - "type": "oauth2", - "description": "This API uses OAuth 2 with the client credentials flow.", - "flows": { - "clientCredentials": { - "tokenUrl": "", - "scopes": {} - } - } - } - } - }, - "security": [ - { - "oAuth": [] - } - ] -} diff --git a/resources/data/api.yml b/resources/data/api.yml new file mode 100644 index 000000000..5135bc775 --- /dev/null +++ b/resources/data/api.yml @@ -0,0 +1,1086 @@ +openapi: 3.0.0 +info: + version: 1.0.0 + title: Web Analytics Italia API + description: Questa interfaccia API si riferisce alle operazioni che le Pubbliche Amministrazioni possono eseguire in interoperabilità per gestire utenti e siti di WAI con credenziali amministrative. + contact: + name: AGID - Web Analytics Italia + url: https://webanalytics.italia.it/contacts + email: wai@agid.gov.it +servers: [] +paths: + /users: + post: + tags: + - Utenti + summary: Crea un nuovo utente + operationId: addUser + requestBody: + description: Dati dell'utente da creare + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/User' + examples: + userExample: + $ref: '#/components/examples/User' + responses: + '201': + description: Dati dell'utente + headers: + Location: + schema: + type: string + format: uri + description: Uri del nuovo utente + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + examples: + Bad Request: + $ref: '#/components/examples/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '422': + description: Dati inviati incompleti o invalidi + content: + application/json: + schema: + $ref: '#/components/schemas/Error422User' + examples: + Unprocessable Entity (User): + $ref: '#/components/examples/Error422User' + get: + tags: + - Utenti + summary: Fornisce l'elenco degli utenti + operationId: getUsers + responses: + '200': + description: Elenco degli utenti + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + /users/{fn}: + parameters: + - $ref: '#/components/parameters/FiscalNumber' + get: + tags: + - Utenti + summary: Fornisce i dati dell'utente specificato + operationId: getUser + responses: + '200': + description: Dati dell'utente + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + put: + tags: + - Utenti + summary: Modifica i dati dell'utente specificato + operationId: updateUser + requestBody: + description: Dati dell'utente da modificare + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + responses: + '200': + description: Dati dell'utente + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '422': + description: Dati inviati incompleti o invalidi + content: + application/json: + schema: + $ref: '#/components/schemas/Error422User' + examples: + Unprocessable Entity (User): + $ref: '#/components/examples/Error422User' + /users/{fn}/suspend: + parameters: + - $ref: '#/components/parameters/FiscalNumber' + patch: + tags: + - Utenti + summary: Sospende l'utente specificato + operationId: suspendUser + responses: + '200': + description: Dati dell'utente + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + '303': + description: Utente già sospeso + headers: + Location: + schema: + type: string + format: uri + description: Uri del sito web + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + /users/{fn}/reactivate: + parameters: + - $ref: '#/components/parameters/FiscalNumber' + patch: + tags: + - Utenti + summary: Riattiva l'utente specificato + operationId: reactivateUser + responses: + '200': + description: Dati dell'utente + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + examples: + userExample: + $ref: '#/components/examples/User' + '303': + description: Utente già attivo + headers: + Location: + schema: + type: string + format: uri + description: Uri del sito web + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + /websites: + post: + tags: + - Siti web + summary: Crea un nuovo sito web + operationId: addWebsite + requestBody: + description: Dati del sito web da creare + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Website' + examples: + WebsiteExample: + $ref: '#/components/examples/Website' + responses: + '201': + description: Dati del sito web + headers: + Location: + schema: + type: string + format: uri + description: Uri del nuovo sito web + content: + application/json: + schema: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteExample: + $ref: '#/components/examples/WebsiteInfo' + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '422': + description: Dati inviati incompleti o invalidi + content: + application/json: + schema: + $ref: '#/components/schemas/Error422Website' + examples: + Unprocessable Entity (Website): + $ref: '#/components/examples/Error422Website' + get: + tags: + - Siti web + summary: Fornisce l'elenco dei siti web + operationId: getWebsites + responses: + '200': + description: Elenco dei siti web + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteInfoExample: + $ref: '#/components/examples/WebsiteInfo' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + /websites/{website}: + parameters: + - $ref: '#/components/parameters/WebsiteSlug' + get: + tags: + - Siti web + summary: Fornisce i dati del sito web specificato + operationId: getWebsite + responses: + '200': + description: Dati del sito web + content: + application/json: + schema: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteInfoExample: + $ref: '#/components/examples/WebsiteInfo' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + put: + tags: + - Siti web + summary: Modifica un sito web specificato + operationId: updateWebsite + requestBody: + description: Dati del sito web da modificare + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Website' + examples: + WebsiteExample: + $ref: '#/components/examples/Website' + responses: + '200': + description: Dati del sito web + content: + application/json: + schema: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteExample: + $ref: '#/components/examples/WebsiteInfo' + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '422': + description: Dati inviati incompleti o invalidi + content: + application/json: + schema: + $ref: '#/components/schemas/Error422Website' + examples: + Unprocessable Entity (Website): + $ref: '#/components/examples/Error422Website' + /websites/{website}/archive: + parameters: + - $ref: '#/components/parameters/WebsiteSlug' + patch: + tags: + - Siti web + summary: Archivia il sito web specificato + operationId: archiveWebsite + responses: + '200': + description: Dati del sito web + content: + application/json: + schema: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteExample: + $ref: '#/components/examples/WebsiteInfo' + '303': + description: Sito web già attivo + headers: + Location: + schema: + type: string + format: uri + description: Uri del sito web + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + /websites/{website}/unarchive: + parameters: + - $ref: '#/components/parameters/WebsiteSlug' + patch: + tags: + - Siti web + summary: Riattiva il sito web specificato + operationId: unarchiveWebsite + responses: + '200': + description: Dati del sito web + content: + application/json: + schema: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteExample: + $ref: '#/components/examples/WebsiteInfo' + '303': + description: Sito web già attivo + headers: + Location: + schema: + type: string + format: uri + description: Uri del sito web + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + /websites/{website}/check: + parameters: + - $ref: '#/components/parameters/WebsiteSlug' + get: + tags: + - Siti web + summary: Verifica l'attivazione del sito web specificato + operationId: checkWebsite + responses: + '200': + description: Sito web attivato + content: + application/json: + schema: + $ref: '#/components/schemas/WebsiteInfo' + examples: + WebsiteExample: + $ref: '#/components/examples/WebsiteInfo' + '303': + description: Sito web già attivo + headers: + Location: + schema: + type: string + format: uri + description: Uri del sito web + '400': + description: Richiesta erronea + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + /websites/{website}/js-snippet: + parameters: + - $ref: '#/components/parameters/WebsiteSlug' + get: + tags: + - Siti web + summary: Fornisce lo snippet javascript del sito web specificato + operationId: websiteJsSnippet + responses: + '200': + description: Snippet javascript del sito web specificato + content: + application/json: + schema: + $ref: '#/components/schemas/JsSnippet' + examples: + WebsiteExample: + $ref: '#/components/examples/JsSnippet' + '401': + description: Dati di autorizzazione non validi + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + examples: + Unauthorized: + $ref: '#/components/examples/Error401' + '403': + description: Permessi non sufficienti per accedere alla risorsa + content: + application/json: + schema: + $ref: '#/components/schemas/Error403' + examples: + Forbidden: + $ref: '#/components/examples/Error403' + '404': + description: Risorsa non trovata + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' +components: + parameters: + WebsiteSlug: + in: path + required: true + name: website + description: Slug del sito web + schema: + $ref: '#/components/schemas/WebsiteSlug' + FiscalNumber: + in: path + required: true + name: fn + description: Codice fiscale dell'utente + schema: + $ref: '#/components/schemas/FiscalNumber' + schemas: + User: + allOf: + - $ref: '#/components/schemas/UserBase' + - properties: + is_admin: + type: boolean + description: Specifica se il nuovo utente dovrà essere un admin (se omesso vale `falso`) + UserInfo: + allOf: + - required: + - first_name + - family_name + - role + properties: + first_name: + type: string + description: Nome dell'utente + family_name: + type: string + description: Cognome dell'utente + - $ref: '#/components/schemas/UserBase' + - properties: + role: + $ref: '#/components/schemas/UserRole' + UserBase: + type: object + required: + - email + - fiscal_number + - permissions + properties: + email: + type: string + pattern: email + description: Indirizzo email dell'utente + fiscal_number: + $ref: '#/components/schemas/FiscalNumber' + permissions: + $ref: '#/components/schemas/WebsitePermissions' + FiscalNumber: + type: string + pattern: ^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$ + description: Codice fiscale dell'utente + UserRole: + type: string + description: Ruolo dell'utente + enum: + - administrator + - delegate + WebsitePermissions: + type: object + description: Elenco dei permessi per ciascun sito web. La chiave della coppia sito/permessi deve essere uno slug di un sito web esistente. + # propertyNames: + # $ref: '#/components/schemas/WebsiteSlug' + additionalProperties: + type: array + description: Elenco dei permessi dell'utente per il sito web + items: + type: string + enum: + - manage-analytics + - read-analytics + WebsiteInfo: + allOf: + - required: + - slug + - status + properties: + slug: + $ref: '#/components/schemas/WebsiteSlug' + status: + $ref: '#/components/schemas/WebsiteStatus' + - $ref: '#/components/schemas/Website' + Website: + type: object + required: + - website_name + - url + - analyticsId + - type + - permissions + description: Sito web + properties: + website_name: + description: Nome del sito web + type: string + pattern: ^(?!\s).+$ + url: + description: Url del sito web + type: string + format: uri + analyticsId: + description: Id del sito web per API analytics + type: integer + type: + $ref: '#/components/schemas/WebsiteType' + permissions: + $ref: '#/components/schemas/UserPermissions' + WebsiteSlug: + type: string + pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$ + description: Slug del sito web + WebsiteType: + type: string + description: Tipologia del sito web + enum: + - institutional website + - informational or thematic website + - services website + - mobile application + WebsiteStatus: + type: string + description: Stato del sito + enum: + - pending + - active + - archived + UserPermissions: + type: object + description: Elenco dei permessi di ciascun utente. La chiave della coppia utente/permessi deve essere il codice fiscale di un utente esistente. + # propertyNames: + # $ref: '#/components/schemas/FiscalNumber' + additionalProperties: + type: array + description: Elenco dei permessi dell'utente sul sito web + items: + type: string + enum: + - manage-analytics + - read-analytics + JsSnippet: + type: object + required: + - slug + - javascriptSnippet + description: Informazioni per il tracciamento del sito web + properties: + slug: + $ref: '#/components/schemas/WebsiteSlug' + javascriptSnippet: + description: Codice javascript per il tracciamento delle visite + type: string + Error400: + type: object + required: + - error_description + - error + properties: + error_description: + type: string + error: + type: string + error_code: + type: string + Error401: + type: object + required: + - error_description + - error + properties: + error_description: + type: string + error: + type: string + Error403: + type: object + required: + - error_description + - error + properties: + error_description: + type: string + error: + type: number + Error404: + type: object + required: + - error_description + - error + properties: + error_description: + type: string + error: + type: string + Error422: + type: object + properties: + message: + type: string + Error422User: + allOf: + - $ref: '#/components/schemas/Error422' + - properties: + errors: + type: object + properties: + email: + type: array + items: + type: string + fiscal_number: + type: array + items: + type: string + permissions: + type: array + items: + type: string + Error422Website: + allOf: + - $ref: '#/components/schemas/Error422' + - properties: + errors: + type: object + properties: + name: + type: array + items: + type: string + url: + type: array + items: + type: string + type: + type: array + items: + type: string + examples: + User: + summary: User + value: + email: name@email.com + fiscal_number: VMGHNY33L47D490P + permissions: + website-slug: + - manage-analytics + Website: + summary: Website + value: + website_name: Nome Sito + url: https://url-sito-web.it/ + type: 1 + permissions: + VMGHNY33L47D490P: + - read-analytics + WebsiteInfo: + summary: Website + value: + website_name: Agenzia per L'Italia Digitale + url: www.agid.gov.it + analyticsId: 123 + slug: wwwagidgovit + status: active + type: institutional website + JsSnippet: + summary: Javascript Snippet for matomo + value: + slug: wwwagidgovit + javascriptSnippet: |- + + + + Error400: + summary: Bad Request + value: + error_description: error + error: bad_request + error_code: '1' + Error401: + summary: Unauthorized + value: + error_description: The access token is invalid or has expired + error: invalid_token + Error403: + summary: Forbidden + value: + error_description: Access to the requested resource is forbidden + error: forbidden + Error404: + summary: Not Found + value: + error_description: The requested resource cannot be found on this server + error: not_found + Error422: + summary: Unprocessable Entity + value: + message: The given data was invalid. + Error422User: + summary: Unprocessable Entity (User) + value: + allOf: + - $ref: '#/components/examples/Error422' + - errors: + email: + - The email address field is required. + fiscal_number: + - The fiscal number field is required. + permissions: + - The permissions field is required. + Error422Website: + summary: Unprocessable Entity (Website) + value: + allOf: + - $ref: '#/components/examples/Error422' + - errors: + website_name: + - The website name field is required. + url: + - The URL field is required. + type: + - The type field is required. + securitySchemes: + oAuth: + type: oauth2 + description: This API uses OAuth 2 with the client credentials flow. + flows: + clientCredentials: + tokenUrl: '' + scopes: {} +security: + - oAuth: [] diff --git a/resources/data/config.yml b/resources/data/config.yml index 88e86e1af..a4e1268d6 100644 --- a/resources/data/config.yml +++ b/resources/data/config.yml @@ -42,12 +42,11 @@ it: # route: open-data - name: FAQ route: faq - - # - name: API - # route: show.swagger - # requires: - # auth: true - # publicAdministration: true + - name: API + route: show.swagger + requires: + auth: true + publicAdministration: true slim_header_links: - name: Piano triennale @@ -71,13 +70,11 @@ it: route: how-to-join - name: Domande frequenti route: faq - - # - name: API - # route: show.swagger - # requires: - # auth: true - # publicAdministration: true - + - name: API + route: show.swagger + requires: + auth: true + publicAdministration: true # - name: Open data # route: open-data - name: Guida utente diff --git a/resources/js/buttons/credentialDelete.js b/resources/js/buttons/credentialDelete.js index 81add61b0..0e314714b 100644 --- a/resources/js/buttons/credentialDelete.js +++ b/resources/js/buttons/credentialDelete.js @@ -1,59 +1,50 @@ -import { upperCaseFirst } from "upper-case-first"; -import Datatable from "../datatables"; -import Notification from "../notification"; -import I18n from "../i18n"; -import AjaxButton from "../ajaxButton"; -import FormButton from "../formButton"; +import { upperCaseFirst } from 'upper-case-first'; +import Datatable from '../datatables'; +import Notification from '../notification'; +import I18n from '../i18n'; +import AjaxButton from '../ajaxButton'; +import FormButton from '../formButton'; export default (() => { const init = () => { const credentialDeleteButtons = [ - ...document.querySelectorAll( - 'a[role="button"][data-type="credentialDelete"]' - ) + ...document.querySelectorAll('a[role="button"][data-type="credentialDelete"]') ]; credentialDeleteButtons.map(credentialDeleteButton => { - const isAjax = "ajax" in credentialDeleteButton.dataset; - const currentAction = I18n.t("eliminazione"); + const isAjax = 'ajax' in credentialDeleteButton.dataset; const confirmation = { - title: upperCaseFirst( - [currentAction, I18n.t("della credenziale")].join(" ") - ), + title: upperCaseFirst([ + I18n.t('eliminazione'), + I18n.t('della credenziale') + ].join(' ')), body: [ - "

", - I18n.t("Stai eliminando la credenziale"), - "" + credentialDeleteButton.dataset.credentialname + "", - "

", - "

" + I18n.t("Sei sicuro?") + "

" - ].join(" "), - image: "/images/website-archive.svg" + '

', + I18n.t('Stai eliminando la credenziale'), + `${credentialDeleteButton.dataset.credentialname}.
`, + I18n.t("L'operazione non è reversibile."), + '

', + '

' + I18n.t('Sei sicuro?') + '

' + ].join(' '), + image: '/images/website-archive.svg' }; const success = () => { Notification.showNotification( - I18n.t("credenziale eliminata"), + I18n.t('credenziale eliminata'), [ - I18n.t("La credenziale"), - "" + - credentialDeleteButton.dataset.credentialname + - "", - I18n.t("è stata eliminata.") - ].join(" "), - "success", - "it-check-circle" + I18n.t('La credenziale'), + `${credentialDeleteButton.dataset.credentialname}`, + I18n.t('è stata eliminata.') + ].join(' '), + 'success', + 'it-check-circle' ); Datatable.reload(); }; - isAjax && - AjaxButton.init( - credentialDeleteButton, - "patch", - confirmation, - success - ); - isAjax || FormButton.init(credentialDeleteButton, "patch", confirmation); + isAjax && AjaxButton.init(credentialDeleteButton, 'patch', confirmation, success); + isAjax || FormButton.init(credentialDeleteButton, 'patch', confirmation); }); }; diff --git a/resources/js/credentialPermissionsToggles.js b/resources/js/credentialPermissionsToggles.js index 924f2e912..2b389890c 100644 --- a/resources/js/credentialPermissionsToggles.js +++ b/resources/js/credentialPermissionsToggles.js @@ -1,6 +1,9 @@ export default (() => { + const credentialTypes = window.credentialTypes; + const credentialPermissions = window.credentialPermissions; + const initTogglesCredentials = () => { - const adminSelect = document.getElementById("type"); + const adminSelect = document.getElementById('type'); const permissionsToggles = [ ...document.querySelectorAll( `input[type="checkbox"][name^="permissions"]:not([disabled])` @@ -8,40 +11,25 @@ export default (() => { ]; permissionsToggles.map(toggle => { - toggle.addEventListener("change", event => { - if (!event.currentTarget.checked) { - adminSelect && (adminSelect.value = "analytics"); - } - - if ( - "R" === event.currentTarget.value && - !event.currentTarget.checked - ) { - document.getElementById( - `permissions[${event.currentTarget.dataset.entity}][]-W` - ).checked = false; + toggle.addEventListener('change', event => { + if (credentialPermissions.read === event.currentTarget.value && !event.currentTarget.checked) { + document.getElementById(`permissions[${event.currentTarget.dataset.entity}][]-${credentialPermissions.write}`).checked = false; } - if ( - "W" === event.currentTarget.value && - event.currentTarget.checked - ) { - document.getElementById( - `permissions[${event.currentTarget.dataset.entity}][]-R` - ).checked = true; + if (credentialPermissions.write === event.currentTarget.value && event.currentTarget.checked) { + document.getElementById(`permissions[${event.currentTarget.dataset.entity}][]-${credentialPermissions.read}`).checked = true; } }); }); - adminSelect && - adminSelect.addEventListener("change", event => { - permissionsToggles.map(toggle => { - const isAdminCredentials = event.target.value === "admin"; - toggle.disabled = isAdminCredentials; - isAdminCredentials - ? toggle.setAttribute("checked", true) - : toggle.removeAttribute("checked"); - }); + adminSelect && adminSelect.addEventListener('change', event => { + permissionsToggles.map(toggle => { + const isAdminCredentials = (event.target.value === credentialTypes.admin); + toggle.disabled = isAdminCredentials; + isAdminCredentials + ? toggle.setAttribute('checked', true) + : toggle.removeAttribute('checked'); }); + }); }; const init = () => { diff --git a/resources/lang/en/enums.php b/resources/lang/en/enums.php index 37f49b32f..5a902c563 100644 --- a/resources/lang/en/enums.php +++ b/resources/lang/en/enums.php @@ -114,8 +114,14 @@ ], CredentialType::class => [ - CredentialType::ADMIN => 'admin', - CredentialType::ANALYTICS => 'analytics', + CredentialType::ADMIN => [ + 'short' => 'amministrativa', + 'long' => 'The administrative credential has the same permissions as an account with an administrator role and can be used to manage all websites and all users.', + ], + CredentialType::ANALYTICS => [ + 'short' => 'analytics', + 'long' => 'The analytics credential can only be used to query statistical reports according to the permissions set.', + ], ], CredentialPermission::class => [ diff --git a/resources/lang/it/enums.php b/resources/lang/it/enums.php index 7a69c9d03..acc206139 100644 --- a/resources/lang/it/enums.php +++ b/resources/lang/it/enums.php @@ -114,8 +114,14 @@ ], CredentialType::class => [ - CredentialType::ADMIN => 'amministrativa', - CredentialType::ANALYTICS => 'analytics', + CredentialType::ADMIN => [ + 'short' => 'amministrativa', + 'long' => 'La credenziale amministrativa ha gli stessi permessi di un account con ruolo di amministatore e può essere usata per gestire tutti i siti web e tutti gli utenti.', + ], + CredentialType::ANALYTICS => [ + 'short' => 'analytics', + 'long' => 'La credenziale analytics può essere usata soltanto per interrogare i report statistici secondo i permessi impostati.', + ], ], CredentialPermission::class => [ diff --git a/resources/sass/_swagger.scss b/resources/sass/_swagger.scss index 3d2536c92..42f78b9bd 100644 --- a/resources/sass/_swagger.scss +++ b/resources/sass/_swagger.scss @@ -19,10 +19,6 @@ font-family: $font-family-sans-serif; } - pre { - overflow: hidden; - } - .auth-wrapper { display: none !important; } diff --git a/resources/views/pages/analytics.blade.php b/resources/views/pages/analytics.blade.php index c37cae783..ccd0c6d92 100644 --- a/resources/views/pages/analytics.blade.php +++ b/resources/views/pages/analytics.blade.php @@ -64,8 +64,8 @@ class="auto-resizeable invisible" @endforeach diff --git a/resources/views/pages/credentials/partials/form.blade.php b/resources/views/pages/credentials/partials/form.blade.php index 9932da4fc..8cc3dd70d 100644 --- a/resources/views/pages/credentials/partials/form.blade.php +++ b/resources/views/pages/credentials/partials/form.blade.php @@ -12,8 +12,7 @@

- + required> @error('credential_name')
{{ $errors->first('credential_name') }}
@else @@ -32,7 +30,8 @@ class="form-control{{ $errors->has('credential_name') ? ' is-invalid' : '' }}" {{ __('Scegli un nome per la credenziale.') }} -
+ @empty($credential) +
@@ -41,11 +40,11 @@ class="form-control{{ $errors->has('credential_name') ? ' is-invalid' : '' }}"
@@ -55,44 +54,91 @@ class="form-control{{ $errors->has('credential_name') ? ' is-invalid' : '' }}"
{{ __('validation.required', ['attribute' => __('validation.attributes.type')]) }}
@enderror
- - {{ __("L'amministratore può gestire tutti i siti web e tutti gli utenti") }} - +
+ +
+ @else +
+
{{ __('tipologia') }}
+
+
+ + {{ strtoupper($type->description) }} + +
+
+

+ + {{ CredentialType::getLongDescription($type->value) }} +

+
+
+
+ @endempty

{{ __('Permessi sui siti web') }}

@error('permissions')
{{ $errors->first('permissions') }}
@enderror -
- {!! __('Per le credenziali di tipologia :analytics_credential, puoi assegnare permessi diversificati per ciascun sito.', [ - 'analytics_credential' => '' . CredentialType::getDescription(CredentialType::ANALYTICS) . '' - ]) !!} -
-
- -
    -
  • {{ CredentialPermission::getLongDescription(CredentialPermission::READ) }}
  • -
  • {{ CredentialPermission::getLongDescription(CredentialPermission::WRITE) }}
  • -
-
+ @unless (($type->value ?? '') === CredentialType::ADMIN) +
+
+
+
+
+ {!! __('Per le credenziali di tipologia :analytics_credential, puoi assegnare permessi diversificati per ciascun sito.', [ + 'analytics_credential' => '' . CredentialType::getDescription(CredentialType::ANALYTICS) . '' + ]) !!} +
+

+

    +
  • {{ CredentialPermission::getLongDescription(CredentialPermission::READ) }}
  • +
  • {{ CredentialPermission::getLongDescription(CredentialPermission::WRITE) }}
  • +
+

+
+
+
-
-
-

- - {!! __('I permessi per le credenziali di tipologia :admin_credential non possono essere modificati.', [ + @endunless + @unless (($type->value ?? '') === CredentialType::ANALYTICS) +

+
+
+
+
+ {!! __('Le credenziali di tipologia :admin_credential hanno permessi completi su tutti i siti.', [ 'admin_credential' => '' . CredentialType::getDescription(CredentialType::ADMIN) . '' ]) !!} - -

-
+ +
+
+
+ @endunless
+ @unless (($type->value ?? '') === CredentialType::ADMIN)
@include('partials.datatable')
+ @endunless +
diff --git a/resources/views/pages/credentials/show.blade.php b/resources/views/pages/credentials/show.blade.php index 09a3c236d..a2612f596 100644 --- a/resources/views/pages/credentials/show.blade.php +++ b/resources/views/pages/credentials/show.blade.php @@ -11,21 +11,21 @@
@@ -33,20 +33,30 @@ class="form-control-plaintext"

- {{__('Il ')}} - {{__('client_secret ')}} - {{__('necessario al flusso')}} - {{__('OAuth2 ')}} - {{__('ti è stato fornito durante la creazione della credenziale.')}} + {!! __('Il :client_secret necessario al flusso :oauth2 ti è stato fornito durante la creazione della credenziale.', [ + 'client_secret' => 'client_secret', + 'oauth2' => 'OAuth2' + ]) !!}

-

{{__('Se necessario poi rigenerare il tuo client_id e client_secret')}}

+

+ {!! __('In caso di necessità puoi rigenerare il tuo :client_secret.', [ + 'client_secret' => 'client_secret', + ]) !!} +

+ @component('layouts.components.link_button', [ - 'link' => $credentialRegenerate, + 'link' => $credentialRegenerateUrl, 'size' => 'lg', ]) - {{ ucfirst(__('Rigenera la credenziale')) }} + {{ ucfirst(__('rigenera la credenziale')) }} @endcomponent
@@ -66,27 +76,25 @@ class="form-control-plaintext"
@component('layouts.components.box') -

{{ __('PERMESSI SUI SITI WEB') }}

+

{{ __('permessi sui siti web') }}

-
{{ __('ruolo') }}
+
{{ __('tipologia') }}
- {{$type === "admin" ? __("Amministratore") : __("Analytics")}} + + {{ strtoupper($type->description) }} +

- {{ - $type === "admin" - ? __('L\'amministratore può gestire i siti web abilitati e tutti gli utenti') - : __('Credenziale Analytics') - }} + {{ CredentialType::getLongDescription($type->value) }}

- @if ($type !== "admin") + @if ($type->isNot(CredentialType::ADMIN)) @include('partials.datatable') @endif
@@ -99,7 +107,7 @@ class="form-control-plaintext" {{ ucfirst(__('modifica')) }} @endcomponent
- @endcomponent + @endcomponent
@endsection diff --git a/routes/api.php b/routes/api.php index 7fe72b124..f2eb82627 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,5 +1,5 @@ group(function () { Route::middleware('api.auth')->group(function () { - Route::get('/', function () { return response()->json(['test' => getallheaders()], 200); }); @@ -23,7 +23,7 @@ ->name('api.users'); Route::post('/', 'UserController@storeApi') ->name('api.users.store'); - Route::get('/{fn}', 'UserController@showApi') + Route::get('/{fn}', 'UserController@showApi') ->name('api.users.show'); Route::put('/{fn}', 'UserController@updateApi') ->name('api.users.update'); @@ -53,9 +53,6 @@ ->name('api.websites.force'); Route::get('/{website}/js-snippet', 'WebsiteController@showJavascriptSnippet') ->name('api.websites.snippet.javascript'); - }); }); }); - -*/ diff --git a/routes/web.php b/routes/web.php index b42affff6..68f35e8ea 100644 --- a/routes/web.php +++ b/routes/web.php @@ -190,7 +190,6 @@ Route::get('/analytics', 'AnalyticsController@index') ->name('analytics'); - /* Route::get('/api', 'SwaggerController@index') ->name('show.swagger'); @@ -232,11 +231,8 @@ Route::patch('/{credential}/delete', 'CredentialsController@delete') ->name('api-credentials.delete'); }); - }); - */ - Route::middleware('authorize.analytics:' . UserPermission::VIEW_LOGS)->group(function () { Route::prefix('/logs')->group(function () { Route::get('/', 'Logs\LogController@show') diff --git a/tests/Feature/ApiTest-disabled.php b/tests/Feature/ApiTest.php similarity index 97% rename from tests/Feature/ApiTest-disabled.php rename to tests/Feature/ApiTest.php index ea4143cce..b2e7d30e5 100644 --- a/tests/Feature/ApiTest-disabled.php +++ b/tests/Feature/ApiTest.php @@ -80,6 +80,20 @@ class ApiTest extends TestCase */ private $client; + /** + * Configured API url. + * + * @var string + */ + private $apiUrl; + + /** + * Configured API bast path. + * + * @var string + */ + private $apiBasePath; + /** * Pre test setup. * @@ -124,6 +138,9 @@ protected function setUp(): void $this->userNonAdministrator->registerAnalyticsServiceAccount(); $this->faker = Factory::create(); + + $this->apiUrl = config('kong-service.api_url'); + $this->apiBasePath = config('kong-service.portal_base_path'); } /** @@ -220,7 +237,7 @@ public function testWebsiteCreate(): void 'Accept' => 'application/json', ]); - $location = config('kong-service.api_url') . str_replace('/api/', '/portal/', route('api.websites.read', ['website' => $slug], false)); + $location = $this->apiUrl . str_replace('/api/', $this->apiBasePath, route('api.websites.read', ['website' => $slug], false)); $response ->assertStatus(201) @@ -453,7 +470,7 @@ public function testUserCreate(): void 'Accept' => 'application/json', ]); - $location = config('kong-service.api_url') . str_replace('/api/', '/portal/', route('api.users.show', ['fn' => $fiscalNumber], false)); + $location = $this->apiUrl . str_replace('/api/', $this->apiBasePath, route('api.users.show', ['fn' => $fiscalNumber], false)); $user = User::findNotSuperAdminByFiscalNumber($fiscalNumber); diff --git a/tests/Feature/CRUDCredentialTest-disabled.php b/tests/Feature/CRUDCredentialTest.php similarity index 100% rename from tests/Feature/CRUDCredentialTest-disabled.php rename to tests/Feature/CRUDCredentialTest.php