diff --git a/app/controllers/api/open_api_clients_controller.rb b/app/controllers/api/open_api_clients_controller.rb index 1de54b1e77..258fe55a2e 100644 --- a/app/controllers/api/open_api_clients_controller.rb +++ b/app/controllers/api/open_api_clients_controller.rb @@ -7,11 +7,12 @@ class API::OpenAPIClientsController < API::APIController def index authorize OpenAPI::Client - @clients = OpenAPI::Client.order(:created_at) + @clients = policy_scope(OpenAPI::Client).order(:created_at) end def create @client = OpenAPI::Client.new(client_params) + @client.user = current_user authorize @client if @client.save render status: :created diff --git a/app/controllers/open_api/v1/base_controller.rb b/app/controllers/open_api/v1/base_controller.rb index a71ccd2647..381295011d 100644 --- a/app/controllers/open_api/v1/base_controller.rb +++ b/app/controllers/open_api/v1/base_controller.rb @@ -6,21 +6,25 @@ module OpenAPI::V1; end # Parameters for OpenAPI endpoints class OpenAPI::V1::BaseController < ActionController::Base # rubocop:disable Rails/ApplicationController include ApplicationHelper + include Pundit protect_from_forgery with: :null_session skip_before_action :verify_authenticity_token before_action :authenticate before_action :increment_calls_count + before_action :check_api_permissions rescue_from ActiveRecord::RecordNotFound, with: :not_found rescue_from OpenAPI::ParameterError, with: :bad_request rescue_from ActionController::ParameterMissing, with: :bad_request + rescue_from Pundit::NotAuthorizedError, with: :render_forbidden + rescue_from TypeError, with: :server_error rescue_from NoMethodError, with: :server_error rescue_from ArgumentError, with: :server_error - helper_method :current_api_client + helper_method :current_user protected @@ -42,18 +46,40 @@ def authenticate def authenticate_token authenticate_with_http_token do |token, _options| - @open_api_client = OpenAPI::Client.find_by(token: token) + api_client = OpenAPI::Client.find_by(token: token) + if api_client&.user + @current_user = api_client.user + @open_api_client = api_client + true + else + false + end end end - def current_api_client - @open_api_client + def check_api_permissions + return if current_user.blank? + + protected_actions = %i[create update destroy delete] + if protected_actions.include?(action_name.to_sym) && !current_user.admin? + render_forbidden + return false + end + true + end + + def current_user + @current_user || super end def render_unauthorized render json: { errors: ['Bad credentials'] }, status: :unauthorized end + def render_forbidden + render json: { errors: ['Forbidden'] }, status: :forbidden + end + private def increment_calls_count diff --git a/app/frontend/src/javascript/controllers/admin/calendar.js b/app/frontend/src/javascript/controllers/admin/calendar.js index ccdd5c830e..641f4c868d 100644 --- a/app/frontend/src/javascript/controllers/admin/calendar.js +++ b/app/frontend/src/javascript/controllers/admin/calendar.js @@ -402,8 +402,8 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state selector: 'body', stepId: 'conclusion', order: 4, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/events.js b/app/frontend/src/javascript/controllers/admin/events.js index 420097e01f..d21a042bfd 100644 --- a/app/frontend/src/javascript/controllers/admin/events.js +++ b/app/frontend/src/javascript/controllers/admin/events.js @@ -361,8 +361,8 @@ Application.Controllers.controller('AdminEventsController', ['$scope', '$state', selector: 'body', stepId: 'conclusion', order: 7, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/invoices.js b/app/frontend/src/javascript/controllers/admin/invoices.js index 68f0fa1467..bff2ed828d 100644 --- a/app/frontend/src/javascript/controllers/admin/invoices.js +++ b/app/frontend/src/javascript/controllers/admin/invoices.js @@ -672,8 +672,8 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I selector: 'body', stepId: 'conclusion', order: 11, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/members.js b/app/frontend/src/javascript/controllers/admin/members.js index d408ef37dd..72aab306fc 100644 --- a/app/frontend/src/javascript/controllers/admin/members.js +++ b/app/frontend/src/javascript/controllers/admin/members.js @@ -572,8 +572,8 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce', selector: 'body', stepId: 'conclusion', order: 11, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/open_api_clients.js b/app/frontend/src/javascript/controllers/admin/open_api_clients.js index 195dd3dc94..577f1f99be 100644 --- a/app/frontend/src/javascript/controllers/admin/open_api_clients.js +++ b/app/frontend/src/javascript/controllers/admin/open_api_clients.js @@ -52,12 +52,12 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien if (client.id != null) { OpenAPIClient.update({ id: client.id }, { open_api_client: client }, function (clientResp) { client = clientResp; - return growl.success(_t('app.admin.open_api_clients.client_successfully_updated')); + return growl.success(_t('app.logged.open_api_clients.client_successfully_updated')); }); } else { OpenAPIClient.save({ open_api_client: client }, function (client) { $scope.clients.push(client); - return growl.success(_t('app.admin.open_api_clients.client_successfully_created')); + return growl.success(_t('app.logged.open_api_clients.client_successfully_created')); }); } @@ -76,8 +76,8 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien resolve: { object () { return { - title: _t('app.admin.open_api_clients.confirmation_required'), - msg: _t('app.admin.open_api_clients.do_you_really_want_to_delete_this_open_api_client') + title: _t('app.logged.open_api_clients.confirmation_required'), + msg: _t('app.logged.open_api_clients.do_you_really_want_to_delete_this_open_api_client') }; } } @@ -85,7 +85,7 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien , () => OpenAPIClient.delete({ id: $scope.clients[index].id }, function () { $scope.clients.splice(index, 1); - return growl.success(_t('app.admin.open_api_clients.client_successfully_deleted')); + return growl.success(_t('app.logged.open_api_clients.client_successfully_deleted')); }) ); @@ -94,8 +94,8 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien resolve: { object () { return { - title: _t('app.admin.open_api_clients.confirmation_required'), - msg: _t('app.admin.open_api_clients.do_you_really_want_to_revoke_this_open_api_access') + title: _t('app.logged.open_api_clients.confirmation_required'), + msg: _t('app.logged.open_api_clients.do_you_really_want_to_revoke_this_open_api_access') }; } } @@ -103,7 +103,7 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien , () => OpenAPIClient.resetToken({ id: client.id }, {}, function (clientResp) { client.token = clientResp.token; - return growl.success(_t('app.admin.open_api_clients.access_successfully_revoked')); + return growl.success(_t('app.logged.open_api_clients.access_successfully_revoked')); }) ); @@ -118,8 +118,8 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien selector: 'body', stepId: 'welcome', order: 0, - title: _t('app.admin.tour.open_api.welcome.title'), - content: _t('app.admin.tour.open_api.welcome.content'), + title: _t('app.logged.tour.open_api.welcome.title'), + content: _t('app.logged.tour.open_api.welcome.content'), placement: 'bottom', orphan: true }); @@ -127,16 +127,16 @@ Application.Controllers.controller('OpenAPIClientsController', ['$scope', 'clien selector: '.heading .documentation-button', stepId: 'doc', order: 1, - title: _t('app.admin.tour.open_api.doc.title'), - content: _t('app.admin.tour.open_api.doc.content'), + title: _t('app.logged.tour.open_api.doc.title'), + content: _t('app.logged.tour.open_api.doc.content'), placement: 'bottom' }); uitour.createStep({ selector: 'body', stepId: 'conclusion', order: 2, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/pricing.js b/app/frontend/src/javascript/controllers/admin/pricing.js index 6d2995a54f..bd729f4b21 100644 --- a/app/frontend/src/javascript/controllers/admin/pricing.js +++ b/app/frontend/src/javascript/controllers/admin/pricing.js @@ -731,8 +731,8 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state', selector: 'body', stepId: 'conclusion', order: 7, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/projects.js b/app/frontend/src/javascript/controllers/admin/projects.js index 710585d8da..2c575c6535 100644 --- a/app/frontend/src/javascript/controllers/admin/projects.js +++ b/app/frontend/src/javascript/controllers/admin/projects.js @@ -300,8 +300,8 @@ Application.Controllers.controller('AdminProjectsController', ['$scope', '$state selector: 'body', stepId: 'conclusion', order: 3, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/settings.js b/app/frontend/src/javascript/controllers/admin/settings.js index 0731c3b419..4f14f2131e 100644 --- a/app/frontend/src/javascript/controllers/admin/settings.js +++ b/app/frontend/src/javascript/controllers/admin/settings.js @@ -431,8 +431,8 @@ Application.Controllers.controller('SettingsController', ['$scope', '$rootScope' selector: 'body', stepId: 'conclusion', order: 11, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/statistics.js b/app/frontend/src/javascript/controllers/admin/statistics.js index fd4409010f..2eb37aab50 100644 --- a/app/frontend/src/javascript/controllers/admin/statistics.js +++ b/app/frontend/src/javascript/controllers/admin/statistics.js @@ -394,8 +394,8 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state', selector: 'body', stepId: 'conclusion', order: 3, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/admin/trainings.js b/app/frontend/src/javascript/controllers/admin/trainings.js index b49df7797f..43e4258dad 100644 --- a/app/frontend/src/javascript/controllers/admin/trainings.js +++ b/app/frontend/src/javascript/controllers/admin/trainings.js @@ -417,8 +417,8 @@ Application.Controllers.controller('TrainingsAdminController', ['$scope', '$stat selector: 'body', stepId: 'conclusion', order: 4, - title: _t('app.admin.tour.conclusion.title'), - content: _t('app.admin.tour.conclusion.content'), + title: _t('app.shared.tour.conclusion.title'), + content: _t('app.shared.tour.conclusion.content'), placement: 'bottom', orphan: true }); diff --git a/app/frontend/src/javascript/controllers/main_nav.js b/app/frontend/src/javascript/controllers/main_nav.js index e28e27e8f8..e84da74f2f 100644 --- a/app/frontend/src/javascript/controllers/main_nav.js +++ b/app/frontend/src/javascript/controllers/main_nav.js @@ -87,6 +87,11 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm linkText: 'app.public.common.subscriptions', linkIcon: 'credit-card', class: 'plans-link' + }, + { + state: 'app.logged.open_api_clients', + linkText: 'app.public.common.open_api_clients', + linkIcon: 'cloud' } ].filter(Boolean); @@ -167,12 +172,6 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm linkText: 'app.public.common.projects', linkIcon: 'tasks', authorizedRoles: ['admin'] - }, - { - state: 'app.admin.open_api_clients', - linkText: 'app.public.common.open_api_clients', - linkIcon: 'cloud', - authorizedRoles: ['admin'] } ].filter(Boolean).concat(Fablab.adminNavLinks); } diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index 610758d88b..a6ab8211c7 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -1299,7 +1299,7 @@ angular.module('application.router', ['ui.router']) }) // OpenAPI Clients - .state('app.admin.open_api_clients', { + .state('app.logged.open_api_clients', { url: '/open_api_clients', views: { 'main@': { diff --git a/app/frontend/src/javascript/services/help.js b/app/frontend/src/javascript/services/help.js index 7847314543..fe9ebc1994 100644 --- a/app/frontend/src/javascript/services/help.js +++ b/app/frontend/src/javascript/services/help.js @@ -15,7 +15,7 @@ Application.Services.factory('Help', ['$rootScope', '$uibModal', '$state', 'Auth 'app.admin.projects': 'projects', 'app.admin.statistics': 'statistics', 'app.admin.settings': 'settings', - 'app.admin.open_api_clients': 'open-api' + 'app.logged.open_api_clients': 'open-api' }; return function (e) { diff --git a/app/frontend/templates/admin/open_api_clients/index.html.erb b/app/frontend/templates/admin/open_api_clients/index.html.erb index 71ddd37aea..fd77f4ce48 100644 --- a/app/frontend/templates/admin/open_api_clients/index.html.erb +++ b/app/frontend/templates/admin/open_api_clients/index.html.erb @@ -9,7 +9,7 @@
Um diese kontextabhängige Hilfe neu zu starten, können Sie jederzeit F1 drücken oder klicken Sie im Benutzermenu auf [? Hilfe].
Zusätzliche Hilfe finden Sie in der Benutzeranleitung (nur auf Französisch).
Das Fab-Manager-Team bietet auch personalisierten Support (Hilfe beim Einstieg, Hilfe bei der Installation, Anpassung etc.), kontaktieren Sie uns für weitere Informationen.
If you want to restart this contextual help, press F1 at any time or click on [? Help] from the user's menu.
If you need additional help, you can check the user guide (only in French for now).
The Fab-manager's team also provides personalized support (help with getting started, help with installation, customization, etc.), contact-us for more info.
Si desea reiniciar esta ayuda contextual, pulse F1 en cualquier momento o haga clic en [? Ayuda] en el menú del usuario.
Si necesitas ayuda adicional , puedes consultar la guía del usuario (sólo en francés por ahora).
El equipo de Fab-manager también ofrece soporte personalizado (ayuda para empezar, ayuda con la instalación, personalización, etc.), contacta con nosotros para más información.
Si vous souhaitez relancer cette aide contextuelle, appuyez sur F1 à n'importe quel moment ou cliquez sur [? Aide] depuis le menu utilisateur.
Si vous avez besoin d'aide supplémentaire, vous pouvez consulter le guide d'utilisation disponible en Français.
L'équipe de Fab-manager propose également du support personnalisé (aide à la prise en main, aide à l'installation, personnalisation, etc.), contactez-nous pour plus d'informations.
Se vuoi riavviare questo aiuto contestuale, premi F1 in qualsiasi momento o clicca su «? Aiuto » dal menu dell'utente.
Se hai bisogno di aiuto aggiuntivo, puoi controllare la guida utente (solo in francese per ora).
Il team di Fab-manager fornisce anche supporto personalizzato (aiuto per iniziare, nell'installazione, personalizzazione, ecc.), contattateci per ulteriori informazioni.
Se você deseja reiniciar esta ajuda contextual, pressione F1 a qualquer momento ou clique em [? Ajuda] do menu do usuário.
Se precisar de ajuda adicional, você pode verificar o guia do usuário (apenas em francês por enquanto).
A equipe do Fab-Gerente também fornece suporte personalizado (ajuda para começar, ajuda com a instalação, personalização, etc.), contacte-nos para mais informações.
Om du vill starta om denna kontextuella hjälp, tryck på F1 när som helst eller klicka på [? Hjälp] från användarens meny.
Om du behöver ytterligare hjälp kan du kolla användarhandboken (endast på franska just nu).
Fab-managerns team ger även personlig support (hjälp med att komma igång, hjälp med installation, anpassning etc., Kontakta oss för mer information.
如果您希望重新开始这个上下文帮助,请随时按下F1键或从用户菜单点击[?帮助]。
如果您需要额外的帮助,您可以查阅用户指南(目前仅有法语版)。
Fab-manager团队还提供个性化支持(入门指导、安装帮助、定制等),请通过联系我们获取更多信息。