mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-17 06:52:27 +01:00
OpenAPI endpoints to create/update/show/delete machines
This commit is contained in:
parent
ed2315d717
commit
30e9f6febf
@ -1,8 +1,11 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
## Next release
|
||||
- Full German translation (thanks to [@korrupt](https://crowdin.com/profile/korrupt))
|
||||
- OpenAPI endpoints to create/update/show/delete machines
|
||||
- Updated environment documentation
|
||||
- Removed useless locales' configuration files
|
||||
- OpenAPI's endpoints will now return more detailed error messages when something wrong occurs
|
||||
- Fix a security issue: updated ini to 1.3.8 to fix [CVE-2020-7788](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7788)
|
||||
− Fix a security issue: updated nokogiri to 1.11.1 to fix [CVE-2020-26247](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26247)
|
||||
- Updated caxlsx to 3.0.4, and the dependencies of caxlsx_rail
|
||||
@ -27,7 +30,7 @@
|
||||
- Removed fab-manager email address from the seeds
|
||||
- Initialize new plans with default prices for machines & spaces
|
||||
- Display a message when no plans are available
|
||||
- Fix a bug: in the settings area, boolean switches are always shown as false
|
||||
- Fix a bug: in the settings' area, boolean switches are always shown as false
|
||||
- Fix a bug: public cards presenting the plans in the public area, have bogus style
|
||||
- Fix a bug: theme primary color is ignored on links
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet`
|
||||
@ -36,7 +39,7 @@
|
||||
|
||||
- Add intermediate step version for upgrades: v4.4.6. This will prevent issues with FootprintDebug if a regeneration is needed
|
||||
- Check postgreSQL status before compiling assets
|
||||
- Improved documentation about the upgrade process
|
||||
- Improved the documentation about the upgrade process
|
||||
- Fix a bug: unable to set libraries locales to their default values (en-us)
|
||||
- Fix a bug: unable to display details about a closed period
|
||||
- Fix a bug: members cannot view available trainings slots
|
||||
@ -44,7 +47,7 @@
|
||||
|
||||
## v4.6.1 2020 October 21
|
||||
|
||||
- Reduced down time during upgrades
|
||||
- Reduced downtime during upgrades
|
||||
- Architecture changes to allow including React.js components into the application
|
||||
- Allow running upgrade scripts from dev ranch
|
||||
- Fix a bug: script mount-webpack.sh was not updating the docker-compose.yml file
|
||||
|
@ -1,5 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Parameters for OpenAPI endpoints
|
||||
class OpenAPI::V1::BaseController < ActionController::Base
|
||||
protect_from_forgery with: :null_session
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :authenticate
|
||||
before_action :increment_calls_count
|
||||
|
||||
@ -7,37 +11,47 @@ class OpenAPI::V1::BaseController < ActionController::Base
|
||||
rescue_from OpenAPI::ParameterError, with: :bad_request
|
||||
rescue_from ActionController::ParameterMissing, with: :bad_request
|
||||
|
||||
rescue_from TypeError, with: :server_error
|
||||
rescue_from NoMethodError, with: :server_error
|
||||
rescue_from ArgumentError, with: :server_error
|
||||
|
||||
helper_method :current_api_client
|
||||
|
||||
protected
|
||||
def not_found
|
||||
render json: { errors: ["Not found"] }, status: :not_found
|
||||
end
|
||||
|
||||
def bad_request
|
||||
render json: { errors: ["Bad request"] }, status: :bad_request
|
||||
end
|
||||
def not_found(exception)
|
||||
render json: { errors: exception }, status: :not_found
|
||||
end
|
||||
|
||||
def authenticate
|
||||
authenticate_token || render_unauthorized
|
||||
end
|
||||
def bad_request(exception)
|
||||
render json: { errors: exception }, status: :bad_request
|
||||
end
|
||||
|
||||
def authenticate_token
|
||||
authenticate_with_http_token do |token, options|
|
||||
@open_api_client = OpenAPI::Client.find_by(token: token)
|
||||
end
|
||||
end
|
||||
def server_error(exception)
|
||||
render json: { error: exception }, status: :internal_server_error
|
||||
end
|
||||
|
||||
def current_api_client
|
||||
@open_api_client
|
||||
end
|
||||
def authenticate
|
||||
authenticate_token || render_unauthorized
|
||||
end
|
||||
|
||||
def render_unauthorized
|
||||
render json: { errors: ['Bad credentials'] }, status: 401
|
||||
def authenticate_token
|
||||
authenticate_with_http_token do |token, _options|
|
||||
@open_api_client = OpenAPI::Client.find_by(token: token)
|
||||
end
|
||||
end
|
||||
|
||||
def current_api_client
|
||||
@open_api_client
|
||||
end
|
||||
|
||||
def render_unauthorized
|
||||
render json: { errors: ['Bad credentials'] }, status: 401
|
||||
end
|
||||
|
||||
private
|
||||
def increment_calls_count
|
||||
@open_api_client.increment_calls_count
|
||||
end
|
||||
|
||||
def increment_calls_count
|
||||
@open_api_client.increment_calls_count
|
||||
end
|
||||
end
|
||||
|
@ -1,3 +1,4 @@
|
||||
# OpenAPI controller for the invoices
|
||||
class OpenAPI::V1::InvoicesController < OpenAPI::V1::BaseController
|
||||
extend OpenAPI::ApiDoc
|
||||
expose_doc
|
||||
@ -5,14 +6,12 @@ class OpenAPI::V1::InvoicesController < OpenAPI::V1::BaseController
|
||||
def index
|
||||
@invoices = Invoice.order(created_at: :desc)
|
||||
|
||||
if params[:user_id].present?
|
||||
@invoices = @invoices.where(user_id: params[:user_id])
|
||||
end
|
||||
@invoices = @invoices.where(user_id: params[:user_id]) if params[:user_id].present?
|
||||
|
||||
if params[:page].present?
|
||||
@invoices = @invoices.page(params[:page]).per(per_page)
|
||||
paginate @invoices, per_page: per_page
|
||||
end
|
||||
return unless params[:page].present?
|
||||
|
||||
@invoices = @invoices.page(params[:page]).per(per_page)
|
||||
paginate @invoices, per_page: per_page
|
||||
end
|
||||
|
||||
def download
|
||||
@ -21,7 +20,8 @@ class OpenAPI::V1::InvoicesController < OpenAPI::V1::BaseController
|
||||
end
|
||||
|
||||
private
|
||||
def per_page
|
||||
params[:per_page] || 20
|
||||
end
|
||||
|
||||
def per_page
|
||||
params[:per_page] || 20
|
||||
end
|
||||
end
|
||||
|
@ -1,8 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# authorized 3rd party softwares can manage the machines through the OpenAPI
|
||||
class OpenAPI::V1::MachinesController < OpenAPI::V1::BaseController
|
||||
extend OpenAPI::ApiDoc
|
||||
expose_doc
|
||||
|
||||
before_action :set_machine, only: %i[show update destroy]
|
||||
|
||||
def index
|
||||
@machines = Machine.order(:created_at)
|
||||
end
|
||||
|
||||
def create
|
||||
@machine = Machine.new(machine_params)
|
||||
if @machine.save
|
||||
render :show, status: :created, location: @machine
|
||||
else
|
||||
render json: @machine.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @machine.update(machine_params)
|
||||
render :show, status: :ok, location: @machine
|
||||
else
|
||||
render json: @machine.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def destroy
|
||||
if @machine.destroyable?
|
||||
@machine.destroy
|
||||
head :no_content
|
||||
else
|
||||
render json: { error: 'has existing reservations' }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def machine_params
|
||||
params.require(:machine).permit(:name, :description, :spec, :disabled,
|
||||
machine_image_attributes: [:attachment])
|
||||
end
|
||||
|
||||
def set_machine
|
||||
@machine = Machine.friendly.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
@ -83,4 +83,100 @@ class OpenAPI::V1::MachinesDoc < OpenAPI::V1::BaseDoc
|
||||
}
|
||||
MACHINES
|
||||
end
|
||||
|
||||
doc_for :create do
|
||||
api :POST, "/#{API_VERSION}/machines", 'Create a machine'
|
||||
formats %w[json multipart/form-data]
|
||||
description 'Create a new machine.'
|
||||
returns code: 201, desc: 'The machine was successfully created'
|
||||
param :machine, Hash, required: true do
|
||||
param :name, String, desc: 'The name of the machine.', required: true
|
||||
param :description, String, desc: 'A long textual description of the machine. HTML is supported.', required: true
|
||||
param :spec, String, desc: 'A long textual description of the technical specifications of the machine. HTML is supported.'
|
||||
param :disabled, [TrueClass, FalseClass], desc: "Should the machine be disabled? If yes, the machine won't be reservable and will be shown apart."
|
||||
param :machine_image_attributes, Hash do
|
||||
param :attachment, ActionDispatch::Http::UploadedFile, required: true, desc: 'Upload a picture for the machine.'
|
||||
end
|
||||
end
|
||||
example <<-MACHINE
|
||||
curl -X POST
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:multipart/form-data"
|
||||
-H "Accept: application/json"
|
||||
-F machine[name]="Epilog laser"
|
||||
-F machine[description]="La découpeuse laser vous permet de découper ou graver des matériaux."
|
||||
-F machine[machine_image_attributes[attachment]]=@epilog.jpeg
|
||||
/open_api/v1/machines
|
||||
|
||||
curl -X POST
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:application/json"
|
||||
-H "Accept: application/json"
|
||||
-d '{"machine": { "name": "DMP Flex 100", "description": "Cette imprimante 3D peut imprimer des métaux." }}'
|
||||
/open_api/v1/machines
|
||||
MACHINE
|
||||
end
|
||||
|
||||
doc_for :update do
|
||||
api :PATCH, "/#{API_VERSION}/machines/:id", 'Update a machine'
|
||||
formats %w[json multipart/form-data]
|
||||
description 'Update an existing machine.'
|
||||
returns code: 200, desc: 'The machine was successfully updated'
|
||||
param :machine, Hash, required: true do
|
||||
param :name, String, desc: 'The name of the machine.', required: true
|
||||
param :description, String, desc: 'A long textual description of the machine. HTML is supported.', required: true
|
||||
param :spec, String, desc: 'A long textual description of the technical specifications of the machine. HTML is supported.'
|
||||
param :disabled, [TrueClass, FalseClass], desc: "Should the machine be disabled? If yes, the machine won't be reservable and will be shown apart."
|
||||
param :machine_image_attributes, Hash do
|
||||
param :attachment, ActionDispatch::Http::UploadedFile, required: true, desc: 'Upload a picture for the machine.'
|
||||
end
|
||||
end
|
||||
example <<-MACHINE
|
||||
curl -X PATCH
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:multipart/form-data"
|
||||
-H "Accept: application/json"
|
||||
-F machine[spec]="Laser CO2 de 60W<br>Surface de travail de 812 x 508 mm"
|
||||
-F machine[machine_image_attributes[attachment]]=@epilog2.jpg
|
||||
/open_api/v1/machines/10
|
||||
|
||||
curl -X PATCH
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Content-Type:application/json"
|
||||
-H "Accept: application/json"
|
||||
-d '{"machine": { "disabled": true }}'
|
||||
/open_api/v1/machines/10
|
||||
MACHINE
|
||||
end
|
||||
|
||||
doc_for :show do
|
||||
api :GET, "/#{API_VERSION}/machines/:id", 'Show a machine'
|
||||
description 'Show all the details of single machine.'
|
||||
example <<-MACHINES
|
||||
# /open_api/v1/machines/1
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Epilog EXT36 Laser",
|
||||
"slug": "decoupeuse-laser",
|
||||
"disabled": false,
|
||||
"updated_at": "2015-02-17T11:06:00.495+01:00",
|
||||
"created_at": "2014-06-30T03:32:31.972+02:00",
|
||||
"description": "La découpeuse Laser, EPILOG Legend 36EXT\r\n\r\nInformations générales :\r\nLa découpeuse laser vous permet de découper ou graver des matériaux. \r\n\r\nPour la découpe, il suffit d'apporter votre fichier vectorisé type illustrator, svg ou dxf avec des \"lignes de coupe\" d'une épaisseur inférieure à 0,01 mm et la machine s'occupera du reste!\r\n\r\nLa gravure est basée sur le spectre noir et blanc. Les nuances sont obtenues par différentes profondeurs de gravure correspondant aux niveaux de gris de votre image. Il suffit pour cela d'apporter une image scannée ou un fichier photo en noir et blanc pour pouvoir reproduire celle-ci sur votre support.\r\n\r\nTypes de matériaux gravables/découpeables ?\r\nDu bois au tissu, du plexiglass au cuir, cette machine permet de découper et graver la plupart des matériaux sauf les métaux. La gravure est néanmoins possible sur les métaux recouverts d'une couche de peinture ou les aluminiums anodisés. \r\nConcernant l'épaisseur des matériaux découpés, il est préférable de ne pas dépasser 5 mm pour le bois et 6 mm pour le plexiglass.\r\n",
|
||||
"spec": "Puissance : 40W\r\nSurface de travail : 914x609 mm \r\nEpaisseur maximale de la matière : 305mm\r\nSource laser : tube laser type CO2\r\nContrôles de vitesse et de puissance : ces deux paramètres sont ajustables en fonction du matériau (de 1% à 100%) .\r\n",
|
||||
"image": "/uploads/machine_image/2514/machine_image.jpg"
|
||||
}
|
||||
MACHINES
|
||||
end
|
||||
|
||||
doc_for :destroy do
|
||||
api :DELETE, "/#{API_VERSION}/machines/:id", 'Delete a machine'
|
||||
description 'Delete an existing machine that does not have any existing reservations.'
|
||||
returns code: 204, desc: 'The machine was successfully deleted'
|
||||
example <<-MACHINE
|
||||
curl -X DELETE
|
||||
-H "Authorization:Token token=xxx"
|
||||
-H "Accept: application/json"
|
||||
/open_api/v1/machines/10
|
||||
MACHINE
|
||||
end
|
||||
end
|
||||
|
@ -1 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.extract! machine, :id, :name, :slug, :disabled, :updated_at, :created_at
|
||||
|
3
app/views/open_api/v1/machines/create.json.jbuilder
Normal file
3
app/views/open_api/v1/machines/create.json.jbuilder
Normal file
@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'open_api/v1/machines/machine', machine: @machine
|
@ -1,3 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.machines @machines do |machine|
|
||||
json.partial! 'open_api/v1/machines/machine', machine: machine
|
||||
json.extract! machine, :description, :spec
|
||||
|
5
app/views/open_api/v1/machines/show.json.jbuilder
Normal file
5
app/views/open_api/v1/machines/show.json.jbuilder
Normal file
@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'open_api/v1/machines/machine', machine: @machine
|
||||
json.extract! @machine, :description, :spec
|
||||
json.image URI.join(root_url, @machine.machine_image.attachment.url) if @machine.machine_image
|
3
app/views/open_api/v1/machines/update.json.jbuilder
Normal file
3
app/views/open_api/v1/machines/update.json.jbuilder
Normal file
@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
json.partial! 'open_api/v1/machines/machine', machine: @machine
|
@ -39,6 +39,7 @@ en:
|
||||
must_be_in_the_past: "The period must be strictly prior to today's date."
|
||||
apipie:
|
||||
api_documentation: "API Documentation"
|
||||
code: "HTTP code"
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "E-mail address \"%{OLD_MAIL}\" is already linked to another account, please input your authentication code."
|
||||
|
@ -39,6 +39,7 @@ fr:
|
||||
must_be_in_the_past: "La période doit être strictement antérieure à la date du jour."
|
||||
apipie:
|
||||
api_documentation: "Documentation de l'API"
|
||||
code: "Code HTTP "
|
||||
#error messages when importing an account from a SSO
|
||||
omniauth:
|
||||
email_already_linked_to_another_account_please_input_your_authentication_code: "L'adresse de courriel \"%{OLD_MAIL}\" est déjà associée à un compte utilisateur, merci de saisir votre code d'authentification."
|
||||
|
@ -189,7 +189,7 @@ Rails.application.routes.draw do
|
||||
resources :trainings
|
||||
resources :user_trainings
|
||||
resources :reservations
|
||||
resources :machines
|
||||
resources :machines, only: %i[index create update show destroy]
|
||||
resources :bookable_machines
|
||||
resources :invoices do
|
||||
get :download, on: :member
|
||||
|
Loading…
x
Reference in New Issue
Block a user