diff --git a/shard.lock b/shard.lock index f8cf4c11..c9e68da7 100644 --- a/shard.lock +++ b/shard.lock @@ -265,9 +265,9 @@ shards: git: https://github.com/place-labs/log-backend.git version: 0.11.4 - placeos-models: + placeos-models: # Overridden git: https://github.com/placeos/models.git - version: 9.39.1 + version: 9.37.5+git.commit.bb84bc1b3545b4330b0477f0d59b824c87a255d5 placeos-resource: git: https://github.com/place-labs/resource.git diff --git a/shard.override.yml b/shard.override.yml index b8c96573..b907c62b 100644 --- a/shard.override.yml +++ b/shard.override.yml @@ -17,7 +17,11 @@ dependencies: placeos-core-client: github: placeos/core-client version: ~> 1.0 - + ulid: github: place-labs/ulid branch: master + + placeos-models: + github: placeos/models + branch: PPT-526 diff --git a/spec/controllers/clients_spec.cr b/spec/controllers/clients_spec.cr new file mode 100644 index 00000000..bf051dc5 --- /dev/null +++ b/spec/controllers/clients_spec.cr @@ -0,0 +1,77 @@ +require "../helper" + +module PlaceOS::Api + describe Clients do + Spec.test_404(Clients.base_route, model_name: Model::Client.table_name, headers: Spec::Authentication.headers) + + describe "CRUD operations", tags: "crud" do + it "create" do + Model::Client.clear + body = PlaceOS::Model::Generator.client.to_json + result = client.post( + Clients.base_route, + body: body, + headers: Spec::Authentication.headers + ) + + result.status_code.should eq 201 + response_model = Model::Client.from_trusted_json(result.body) + response_model.destroy + end + + it "update" do + Model::Client.clear + model = Model::Generator.client.save! + original_name = model.name + + model.name = random_name + + id = model.id.as(String) + path = File.join(Clients.base_route, id) + result = client.patch( + path: path, + body: model.to_json, + headers: Spec::Authentication.headers, + ) + + result.status_code.should eq 200 + updated = Model::Client.from_trusted_json(result.body) + + updated.id.should eq model.id + updated.name.should_not eq original_name + updated.destroy + end + + it "show" do + Model::Client.clear + model = PlaceOS::Model::Generator.client.save! + model.persisted?.should be_true + id = model.id.as(String) + result = client.get( + path: File.join(Clients.base_route, id.to_s), + headers: Spec::Authentication.headers, + ) + + result.status_code.should eq 200 + response_model = Model::Client.from_trusted_json(result.body) + response_model.id.should eq id + + model.destroy + end + + it "destroy" do + Model::Client.clear + model = PlaceOS::Model::Generator.client.save! + model.persisted?.should be_true + id = model.id.as(String) + result = client.delete( + path: File.join(Clients.base_route, id.to_s), + headers: Spec::Authentication.headers + ) + + result.success?.should eq true + Model::Client.find?(id).should be_nil + end + end + end +end diff --git a/spec/migration/Dockerfile b/spec/migration/Dockerfile index 57ff5e26..e601fbe3 100644 --- a/spec/migration/Dockerfile +++ b/spec/migration/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /app COPY . /app -RUN git clone https://github.com/PlaceOS/models +RUN git clone -b PPT-526 https://github.com/PlaceOS/models RUN mv ./models/migration/db ./db ENV PATH /app/bin:$PATH diff --git a/src/placeos-rest-api/controllers/clients.cr b/src/placeos-rest-api/controllers/clients.cr new file mode 100644 index 00000000..b59e0c98 --- /dev/null +++ b/src/placeos-rest-api/controllers/clients.cr @@ -0,0 +1,68 @@ +require "./application" + +module PlaceOS::Api + class Clients < Application + base "/api/engine/v2/clients/" + + # Scopes + ############################################################################################### + + before_action :can_read, only: [:index, :show] + before_action :can_write, only: [:create, :update, :destroy, :remove] + + before_action :check_admin, except: [:index, :show] + before_action :check_support, only: [:index, :show] + + ############################################################################################### + + @[AC::Route::Filter(:before_action, except: [:index, :create])] + def find_current_client(id : String) + Log.context.set(client_id: id) + # Find will raise a 404 (not found) if there is an error + @current_client = Model::Client.find!(id) + end + + getter! current_client : Model::Client + + ############################################################################################### + + # list the clients (all when current authority doesn't have any associated client) or (only clients which belong to this particular client) + @[AC::Route::GET("/")] + def index : Array(Model::Client) + if cid = current_authority.try &.client_id + Model::Client.where("id = ? or parent_id = ?", cid, cid).to_a + else + Model::Client.all.to_a + end + end + + # show the selected client + @[AC::Route::GET("/:id")] + def show : Model::Client + current_client + end + + # udpate a client details + @[AC::Route::PATCH("/:id", body: :client)] + @[AC::Route::PUT("/:id", body: :client)] + def update(client : Model::Client) : Model::Client + current = current_client + current.assign_attributes(client) + raise Error::ModelValidation.new(current.errors) unless current.save + current + end + + # add a new client + @[AC::Route::POST("/", body: :client, status_code: HTTP::Status::CREATED)] + def create(client : Model::Client) : Model::Client + raise Error::ModelValidation.new(client.errors) unless client.save + client + end + + # remove a client + @[AC::Route::DELETE("/:id", status_code: HTTP::Status::ACCEPTED)] + def destroy : Nil + current_client.destroy + end + end +end