Last active
August 29, 2015 14:06
-
-
Save zmajstor/2587f9ff72c0ddfacff1 to your computer and use it in GitHub Desktop.
Simple API sample (responds with json or xml)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class API::V1::DevicesController < ApplicationController | |
before_filter :authenticate! | |
before_filter :find_device, only: [:update, :destroy, :capability, :push_mdm_commands] | |
skip_before_filter :verify_authenticity_token | |
respond_to :json, :xml | |
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found_error | |
# curl -v -k -X GET -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Token token=justesting' https://localhost:8443/api/v1/devices | |
# default response format is json, append .xml for XML output: https://localhost:8443/api/v1/devices.xml | |
# TODO implement page-ing and remove limit | |
def index | |
devices = Device.api_select.order(:id).limit(300) | |
respond_with devices | |
end | |
# curl -v -k -X GET -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Token token=justesting' https://localhost:8443/api/v1/devices/filter_by/username/zm | |
# https://localhost:8443/api/v1/devices/filter_by/username/zm.xml | |
def filter_devices | |
if Device.api_attrs.include?(params[:field]) | |
@devices = Device.api_filter_by(params[:field] => params[:value]).limit(300) if params[:value] | |
respond_with @devices | |
else | |
respond_with_error "Invalid filter" | |
end | |
end | |
# https://localhost:8443/api/v1/devices/3 | |
# https://localhost:8443/api/v1/devices/3.xml | |
def show | |
if (@device = Device.api_filter_by({ id: params[:id].to_i }, { all: true }).first) | |
respond_with @device | |
else | |
respond_with_error "Invalid device" | |
end | |
end | |
# https://localhost:8443/api/v1/devices/3/capability | |
# https://localhost:8443/api/v1/devices/3/capability.xml | |
def capability | |
if (device_mdm_commands = @device.capable_for_mdm_commands) | |
respond_with({ mdm_commands: device_mdm_commands }) | |
else | |
respond_with_error "Device capability error" | |
end | |
end | |
# show array of editable attrs | |
def editable | |
respond_with(Device.api_attrs(update: true)) | |
end | |
# curl -v -k -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Basic encoded==' -d '{"device": {"serial":"12345"}}' https://localhost:8443/api/v1/devices/ | |
# curl -v -k -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Token token=justesting' -d '{"device": {"serial":"12345"}}' https://localhost:8443/api/v1/devices/ | |
def create | |
serial = params[:device][:serial].to_s.upcase | |
if (@device = Device.find_or_create_by_serial(serial)) | |
respond_with(@device, only: :id, status: :created, location: api_v1_device_path(@device)) | |
else | |
respond_with_error "Device create failed for serial #{serial}" | |
end | |
end | |
# curl -v -k -X PUT -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Token token=justesting' -d '{"device": {"note":"12345"}}' https://localhost:8443/api/v1/devices/8 | |
def update | |
valid_keys = Device.api_attrs(update: true).map(&:to_sym) | |
if @device.update_attributes(params[:device].slice(*valid_keys)) | |
respond_with(@device, only: :id, status: :ok, location: api_v1_device_path(@device)) | |
else | |
respond_with_error @device.errors | |
end | |
end | |
# Push MDM Commands to Device curl sample: | |
# curl -v -k -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Basic encoded==' -d '{"mdm_commands": [{"request_type":"DeviceInformation"}, {"request_type":"RemoveProfile", "identifier":"net.promdm.profile4", "force":"true"} ]}' https://localhost:8443/api/v1/devices/3/push_mdm_commands | |
def push_mdm_commands | |
if params['mdm_commands'].respond_to? :each | |
params['mdm_commands'].each do |cmd| | |
if cmd['request_type'].present? | |
queued, msg = @device.queue_deduplicated_command(cmd.symbolize_keys) | |
@device.errors.add(:base, "#{msg} on MDM Command #{cmd} for device id #{@device.id}") unless queued | |
end | |
@device.errors.add(:base, "push_notification failed for device id #{@device.id}") unless @device.push_notification | |
end | |
else | |
@device.errors.add(:base, "invalid mdm_commands") | |
end | |
if @device.errors.empty? | |
head :no_content, status: :ok, nothing: true | |
else | |
respond_with_error @device.errors.full_messages | |
end | |
rescue => e | |
logger.error "push_mdm_commands: #{e.message}" | |
respond_with_error e.message | |
end | |
# curl -v -k -X DELETE -H "Content-Type: application/json" -H "Accept: application/json" -H 'Authorization: Token token=justesting' https://localhost:8443/api/v1/devices/1 | |
def destroy | |
if @device.destroy | |
head :no_content, status: :ok, nothing: true | |
else | |
respond_with_error "Device delete failed" | |
end | |
end | |
protected | |
def authenticate! | |
authenticate_token || render_unauthorized | |
end | |
def authenticate_token | |
authenticate_with_http_token do |token, options| | |
token == API_TOKEN if defined?(API_TOKEN) | |
end | |
end | |
def render_unauthorized | |
self.headers['WWW-Authenticate'] = 'Token realm="Application"' | |
respond_with({ error: 'Bad credentials' }, status: 401, location: nil) | |
end | |
def respond_with_error(msg) | |
respond_with({ error: msg }, status: :unprocessable_entity, location: nil) | |
end | |
def record_not_found_error | |
# head :not_found, nothing: true | |
respond_with({ error: 'Resource not found' }, status: 404, location: nil) | |
end | |
private | |
def find_device | |
@device = Device.find(params[:id]) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment