users and metacodes api endpoints
This commit is contained in:
parent
c90460802e
commit
2eae89a6b7
23 changed files with 405 additions and 10 deletions
10
app/controllers/api/v2/metacodes_controller.rb
Normal file
10
app/controllers/api/v2/metacodes_controller.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class MetacodesController < RestfulController
|
||||
def searchable_columns
|
||||
[:name]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -70,7 +70,8 @@ module Api
|
|||
|
||||
def default_scope
|
||||
{
|
||||
embeds: embeds
|
||||
embeds: embeds,
|
||||
current_user: current_user
|
||||
}
|
||||
end
|
||||
|
||||
|
|
24
app/controllers/api/v2/users_controller.rb
Normal file
24
app/controllers/api/v2/users_controller.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class UsersController < RestfulController
|
||||
def current
|
||||
@user = current_user
|
||||
authorize @user
|
||||
return show
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def searchable_columns
|
||||
[:name]
|
||||
end
|
||||
|
||||
# only ask serializer to return is_admin field if we're on the
|
||||
# current_user action
|
||||
def default_scope
|
||||
super.merge(show_is_admin: action_name == 'current')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
27
app/policies/metacode_policy.rb
Normal file
27
app/policies/metacode_policy.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
class MetacodePolicy < ApplicationPolicy
|
||||
def index?
|
||||
true
|
||||
end
|
||||
|
||||
def show?
|
||||
true
|
||||
end
|
||||
|
||||
def create?
|
||||
user.is_admin
|
||||
end
|
||||
|
||||
def update?
|
||||
user.is_admin
|
||||
end
|
||||
|
||||
def destroy?
|
||||
false
|
||||
end
|
||||
|
||||
class Scope < Scope
|
||||
def resolve
|
||||
scope.all
|
||||
end
|
||||
end
|
||||
end
|
41
app/policies/user_policy.rb
Normal file
41
app/policies/user_policy.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
class UserPolicy < ApplicationPolicy
|
||||
def index?
|
||||
user.present?
|
||||
end
|
||||
|
||||
def show?
|
||||
user.present?
|
||||
end
|
||||
|
||||
def create?
|
||||
fail 'Create should be handled by Devise'
|
||||
end
|
||||
|
||||
def update?
|
||||
user == record
|
||||
end
|
||||
|
||||
def destroy?
|
||||
false
|
||||
end
|
||||
|
||||
def details?
|
||||
show?
|
||||
end
|
||||
|
||||
def updatemetacodes?
|
||||
update?
|
||||
end
|
||||
|
||||
# API action
|
||||
def current?
|
||||
user == record
|
||||
end
|
||||
|
||||
class Scope < Scope
|
||||
def resolve
|
||||
return scope.all if user.present?
|
||||
scope.none
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,9 +4,8 @@ module Api
|
|||
class MetacodeSerializer < ApplicationSerializer
|
||||
attributes :id,
|
||||
:name,
|
||||
:manual_icon,
|
||||
:color,
|
||||
:aws_icon
|
||||
:icon
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,9 +5,11 @@ module Api
|
|||
attributes :id,
|
||||
:name,
|
||||
:avatar,
|
||||
:is_admin,
|
||||
:generation
|
||||
|
||||
attribute :is_admin,
|
||||
if: -> { scope[:show_is_admin] && scope[:current_user] == object }
|
||||
|
||||
def avatar
|
||||
object.image.url(:sixtyfour)
|
||||
end
|
||||
|
|
|
@ -63,13 +63,17 @@ Metamaps::Application.routes.draw do
|
|||
|
||||
namespace :api, path: '/api', default: { format: :json } do
|
||||
namespace :v2, path: '/v2' do
|
||||
resources :metacodes, only: [:index, :show]
|
||||
resources :mappings, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :maps, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :synapses, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :topics, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :mappings, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :tokens, only: [:create, :destroy] do
|
||||
get :my_tokens, on: :collection
|
||||
end
|
||||
resources :topics, only: [:index, :create, :show, :update, :destroy]
|
||||
resources :users, only: [:index, :show] do
|
||||
get :current, on: :collection
|
||||
end
|
||||
end
|
||||
namespace :v1, path: '/v1' do
|
||||
# api v1 routes all lead to a deprecation error method
|
||||
|
|
|
@ -16,19 +16,23 @@ traits:
|
|||
searchable: !include traits/searchable.raml
|
||||
|
||||
schemas:
|
||||
topic: !include schemas/_topic.json
|
||||
synapse: !include schemas/_synapse.json
|
||||
map: !include schemas/_map.json
|
||||
mapping: !include schemas/_mapping.json
|
||||
metacode: !include schemas/_metacode.json
|
||||
synapse: !include schemas/_synapse.json
|
||||
token: !include schemas/_token.json
|
||||
topic: !include schemas/_topic.json
|
||||
user: !include schemas/_user.json
|
||||
|
||||
#resourceTypes:
|
||||
# base: !include resourceTypes/base.raml
|
||||
# item: !include resourceTypes/item.raml
|
||||
# collection: !include resourceTypes/collection.raml
|
||||
|
||||
/topics: !include apis/topics.raml
|
||||
/synapses: !include apis/synapses.raml
|
||||
/maps: !include apis/maps.raml
|
||||
/mappings: !include apis/mappings.raml
|
||||
/metacodes: !include api/metacodes.raml
|
||||
/synapses: !include apis/synapses.raml
|
||||
/tokens: !include apis/tokens.raml
|
||||
/topics: !include apis/topics.raml
|
||||
/users: !include apis/users.raml
|
||||
|
|
16
doc/api/apis/metacodes.raml
Normal file
16
doc/api/apis/metacodes.raml
Normal file
|
@ -0,0 +1,16 @@
|
|||
#type: collection
|
||||
get:
|
||||
is: [ searchable: { searchFields: "name" }, orderable, pageable ]
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
example: !include ../examples/metacodes.json
|
||||
/{id}:
|
||||
#type: item
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
example: !include ../examples/metacode.json
|
24
doc/api/apis/users.raml
Normal file
24
doc/api/apis/users.raml
Normal file
|
@ -0,0 +1,24 @@
|
|||
#type: collection
|
||||
get:
|
||||
is: [ searchable: { searchFields: "name" }, orderable, pageable ]
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
example: !include ../examples/users.json
|
||||
/current:
|
||||
#type: item
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
example: !include ../examples/current_user.json
|
||||
/{id}:
|
||||
#type: item
|
||||
get:
|
||||
responses:
|
||||
200:
|
||||
body:
|
||||
application/json:
|
||||
example: !include ../examples/user.json
|
8
doc/api/examples/metacode.json
Normal file
8
doc/api/examples/metacode.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "Action",
|
||||
"color": "#BD6C85",
|
||||
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_action.png"
|
||||
}
|
||||
}
|
30
doc/api/examples/metacodes.json
Normal file
30
doc/api/examples/metacodes.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Action",
|
||||
"color": "#BD6C85",
|
||||
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_action.png"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Activity",
|
||||
"color": "#6EBF65",
|
||||
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_activity.png"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Catalyst",
|
||||
"color": "#EF8964",
|
||||
"icon": "https://s3.amazonaws.com/metamaps-assets/metacodes/blueprint/96px/bp_catalyst.png"
|
||||
}
|
||||
],
|
||||
"page": {
|
||||
"current_page": 1,
|
||||
"next_page": 2,
|
||||
"prev_page": 0,
|
||||
"total_pages": 16,
|
||||
"total_count": 47,
|
||||
"per": 3
|
||||
}
|
||||
}
|
9
doc/api/examples/user.json
Normal file
9
doc/api/examples/user.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"data": {
|
||||
"id": 1,
|
||||
"name": "user",
|
||||
"avatar": "https://s3.amazonaws.com/metamaps-assets/site/user.png",
|
||||
"generation": 0,
|
||||
"is_admin": false
|
||||
}
|
||||
}
|
24
doc/api/examples/users.json
Normal file
24
doc/api/examples/users.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "user",
|
||||
"avatar": "https://s3.amazonaws.com/metamaps-assets/site/user.png",
|
||||
"generation": 0
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "admin",
|
||||
"avatar": "https://s3.amazonaws.com/metamaps-assets/site/user.png",
|
||||
"generation": 0
|
||||
}
|
||||
],
|
||||
"page": {
|
||||
"current_page": 1,
|
||||
"next_page": 0,
|
||||
"prev_page": 0,
|
||||
"total_pages": 1,
|
||||
"total_count": 2,
|
||||
"per": 25
|
||||
}
|
||||
}
|
24
doc/api/schemas/_metacode.json
Normal file
24
doc/api/schemas/_metacode.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "Metacode",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "_id.json"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"color": {
|
||||
"type": "string"
|
||||
},
|
||||
"icon": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"color",
|
||||
"icon"
|
||||
]
|
||||
}
|
28
doc/api/schemas/_user.json
Normal file
28
doc/api/schemas/_user.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "User",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "_id.json"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"generation": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"is_admin": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"avatar",
|
||||
"generation"
|
||||
]
|
||||
}
|
12
doc/api/schemas/metacode.json
Normal file
12
doc/api/schemas/metacode.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Metacode Envelope",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "_metacode.json"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
]
|
||||
}
|
19
doc/api/schemas/metacodes.json
Normal file
19
doc/api/schemas/metacodes.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "Metacodes",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "_metacode.json"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"$ref": "_page.json"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"page"
|
||||
]
|
||||
}
|
12
doc/api/schemas/user.json
Normal file
12
doc/api/schemas/user.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "User Envelope",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "_user.json"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
]
|
||||
}
|
19
doc/api/schemas/users.json
Normal file
19
doc/api/schemas/users.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "Users",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "_user.json"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"$ref": "_page.json"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"page"
|
||||
]
|
||||
}
|
25
spec/api/v2/metacodes_api_spec.rb
Normal file
25
spec/api/v2/metacodes_api_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'metacodes API', type: :request do
|
||||
let(:user) { create(:user, admin: true) }
|
||||
let(:token) { create(:token, user: user).token }
|
||||
let(:metacode) { create(:metacode) }
|
||||
|
||||
it 'GET /api/v2/metacodes' do
|
||||
create_list(:metacode, 5)
|
||||
get '/api/v2/metacodes', params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:metacodes)
|
||||
expect(JSON.parse(response.body)['data'].count).to eq 5
|
||||
end
|
||||
|
||||
it 'GET /api/v2/metacodes/:id' do
|
||||
get "/api/v2/metacodes/#{metacode.id}", params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:metacode)
|
||||
expect(JSON.parse(response.body)['data']['id']).to eq metacode.id
|
||||
end
|
||||
end
|
33
spec/api/v2/users_api_spec.rb
Normal file
33
spec/api/v2/users_api_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'users API', type: :request do
|
||||
let(:user) { create(:user, admin: true) }
|
||||
let(:token) { create(:token, user: user).token }
|
||||
let(:record) { create(:user) }
|
||||
|
||||
it 'GET /api/v2/users' do
|
||||
create_list(:user, 5)
|
||||
get '/api/v2/users', params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:users)
|
||||
expect(JSON.parse(response.body)['data'].count).to eq 6
|
||||
end
|
||||
|
||||
it 'GET /api/v2/users/:id' do
|
||||
get "/api/v2/users/#{record.id}", params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:user)
|
||||
expect(JSON.parse(response.body)['data']['id']).to eq record.id
|
||||
end
|
||||
|
||||
it 'GET /api/v2/users/current' do
|
||||
get '/api/v2/users/current', params: { access_token: token }
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response).to match_json_schema(:user)
|
||||
expect(JSON.parse(response.body)['data']['id']).to eq user.id
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue