Skip to content

Commit

Permalink
WIP: Implementing the OAuth2 pieces of fetching a remote vital sign. …
Browse files Browse the repository at this point in the history
…This commit still has failing tests.
  • Loading branch information
eedrummer committed Aug 28, 2012
1 parent 0f59a0e commit a118fb4
Show file tree
Hide file tree
Showing 18 changed files with 341 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ group :test do
gem 'feedzirra'
gem 'cover_me'
gem 'factory_girl_rails'
gem 'fakeweb'
end
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ GEM
factory_girl_rails (4.0.0)
factory_girl (~> 4.0.0)
railties (>= 3.0.0)
fakeweb (1.3.0)
feedzirra (0.0.24)
activesupport (>= 2.3.8)
builder (>= 2.1.2)
Expand Down Expand Up @@ -261,6 +262,7 @@ DEPENDENCIES
devise
devise_oauth2_providable!
factory_girl_rails
fakeweb
feedzirra
health-data-standards!
heroku
Expand Down
19 changes: 19 additions & 0 deletions app/controllers/vital_sign_callback_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class VitalSignCallbackController < ApplicationController
def access_code
# The way we pair up the access code sent back from the resource host with a feed
# is by looking for the first VitalSignAuth without an access_token. In theory,
# we should be able to use the state parameter as described in OAuth 2, but it
# looks like Rack::OAuth2 doesn't support it. This code should work assuming the
# same user doesn't try to gain access to two different vital sign feeds at the
# same time.
vsa = current_user.vital_sign_auths.where(access_token: nil).first
access_token = vsa.vital_sign_feed.obtain_access_token(params[:code], url_for(controller: 'vital_sign_callback',
action: 'access_code'))
vsa.access_token = access_token.to_s
vsa.save!

#TODO: fetch the new vital signs

redirect_to vsa.vital_sign_feed.record
end
end
83 changes: 83 additions & 0 deletions app/controllers/vital_sign_hosts_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
class VitalSignHostsController < ApplicationController
# GET /vital_sign_hosts
# GET /vital_sign_hosts.json
def index
@vital_sign_hosts = VitalSignHost.all

respond_to do |format|
format.html # index.html.erb
format.json { render json: @vital_sign_hosts }
end
end

# GET /vital_sign_hosts/1
# GET /vital_sign_hosts/1.json
def show
@vital_sign_host = VitalSignHost.find(params[:id])

respond_to do |format|
format.html # show.html.erb
format.json { render json: @vital_sign_host }
end
end

# GET /vital_sign_hosts/new
# GET /vital_sign_hosts/new.json
def new
@vital_sign_host = VitalSignHost.new

respond_to do |format|
format.html # new.html.erb
format.json { render json: @vital_sign_host }
end
end

# GET /vital_sign_hosts/1/edit
def edit
@vital_sign_host = VitalSignHost.find(params[:id])
end

# POST /vital_sign_hosts
# POST /vital_sign_hosts.json
def create
@vital_sign_host = VitalSignHost.new(params[:vital_sign_host])

respond_to do |format|
if @vital_sign_host.save
format.html { redirect_to @vital_sign_host, notice: 'Vital sign host was successfully created.' }
format.json { render json: @vital_sign_host, status: :created, location: @vital_sign_host }
else
format.html { render action: "new" }
format.json { render json: @vital_sign_host.errors, status: :unprocessable_entity }
end
end
end

# PUT /vital_sign_hosts/1
# PUT /vital_sign_hosts/1.json
def update
@vital_sign_host = VitalSignHost.find(params[:id])

respond_to do |format|
if @vital_sign_host.update_attributes(params[:vital_sign_host])
format.html { redirect_to @vital_sign_host, notice: 'Vital sign host was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @vital_sign_host.errors, status: :unprocessable_entity }
end
end
end

# DELETE /vital_sign_hosts/1
# DELETE /vital_sign_hosts/1.json
def destroy
@vital_sign_host = VitalSignHost.find(params[:id])
@vital_sign_host.destroy

respond_to do |format|
format.html { redirect_to vital_sign_hosts_url }
format.json { head :no_content }
end
end
end
3 changes: 3 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class User
field :dob, type: String
field :insurance, type: String

## Information to make OAuth 2 requests for vital signs
embeds_many :vital_sign_auths

symbolize :gender, :in => {
male: "Male",
female: "Female"}, :default => :male, :scopes => true
Expand Down
9 changes: 9 additions & 0 deletions app/models/vital_sign_auth.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class VitalSignAuth
include Mongoid::Document

embedded_in :user

field :access_token, type: String

belongs_to :vital_sign_feed
end
25 changes: 25 additions & 0 deletions app/models/vital_sign_feed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class VitalSignFeed
include Mongoid::Document

field :url, type: String

belongs_to :vital_sign_host
belongs_to :record

def fetch(vital_sign_auth)
token = Rack::OAuth2::AccessToken::Bearer.new(:access_token => vital_sign_auth.access_token)
token.get(url)
end

def obtain_access_token(authorization_code, redirect_uri)
client = Rack::OAuth2::Client.new(
:identifier => vital_sign_host.client_id,
:secret => vital_sign_host.client_secret,
:redirect_uri => redirect_uri,
:host => vital_sign_host.hostname
)

client.authorization_code = authorization_code
client.access_token!
end
end
8 changes: 8 additions & 0 deletions app/models/vital_sign_host.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class VitalSignHost
include Mongoid::Document
field :hostname, :type => String
field :client_id, :type => String
field :client_secret, :type => String

has_many :vital_sign_feeds
end
29 changes: 29 additions & 0 deletions app/views/vital_sign_hosts/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<%= form_for(@vital_sign_host) do |f| %>
<% if @vital_sign_host.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@vital_sign_host.errors.count, "error") %> prohibited this vital_sign_host from being saved:</h2>

<ul>
<% @vital_sign_host.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= f.label :hostname %><br />
<%= f.text_field :hostname %>
</div>
<div class="field">
<%= f.label :client_id %><br />
<%= f.text_field :client_id %>
</div>
<div class="field">
<%= f.label :client_secret %><br />
<%= f.text_field :client_secret %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
6 changes: 6 additions & 0 deletions app/views/vital_sign_hosts/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<h1>Editing vital_sign_host</h1>

<%= render 'form' %>

<%= link_to 'Show', @vital_sign_host %> |
<%= link_to 'Back', vital_sign_hosts_path %>
27 changes: 27 additions & 0 deletions app/views/vital_sign_hosts/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<h1>Listing vital_sign_hosts</h1>

<table>
<tr>
<th>Hostname</th>
<th>Client</th>
<th>Client secret</th>
<th></th>
<th></th>
<th></th>
</tr>

<% @vital_sign_hosts.each do |vital_sign_host| %>
<tr>
<td><%= vital_sign_host.hostname %></td>
<td><%= vital_sign_host.client_id %></td>
<td><%= vital_sign_host.client_secret %></td>
<td><%= link_to 'Show', vital_sign_host %></td>
<td><%= link_to 'Edit', edit_vital_sign_host_path(vital_sign_host) %></td>
<td><%= link_to 'Destroy', vital_sign_host, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>

<br />

<%= link_to 'New Vital sign host', new_vital_sign_host_path %>
5 changes: 5 additions & 0 deletions app/views/vital_sign_hosts/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>New vital_sign_host</h1>

<%= render 'form' %>

<%= link_to 'Back', vital_sign_hosts_path %>
20 changes: 20 additions & 0 deletions app/views/vital_sign_hosts/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<p id="notice"><%= notice %></p>

<p>
<b>Hostname:</b>
<%= @vital_sign_host.hostname %>
</p>

<p>
<b>Client:</b>
<%= @vital_sign_host.client_id %>
</p>

<p>
<b>Client secret:</b>
<%= @vital_sign_host.client_secret %>
</p>


<%= link_to 'Edit', edit_vital_sign_host_path(@vital_sign_host) %> |
<%= link_to 'Back', vital_sign_hosts_path %>
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
HdataServer::Application.routes.draw do

get "vital_sign_callback/access_code"

resources :vital_sign_hosts

##
resources :ref_consult_requests
match "ref_consult_requests/new/:id" => "ref_consult_requests#new", :as => :new_ref_consult_request_patient, :method => :get
Expand Down
12 changes: 12 additions & 0 deletions test/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,16 @@
sendRequestProviderId 1
end

factory :vital_sign_host do
hostname 'foo.bar.com'
client_id '1234'
client_secret '5678'
end

factory :vital_sign_feed do
url 'http://foo.bar.com/vs1'
vital_sign_host {FactoryGirl.build :vital_sign_host}
record {FactoryGirl.build :record}
end

end
28 changes: 28 additions & 0 deletions test/functional/vital_sign_callback_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'test_helper'

class VitalSignCallbackControllerTest < ActionController::TestCase
include Devise::TestHelpers

setup do
@user = FactoryGirl.create(:user)
@vital_sign_feed = FactoryGirl.create(:vital_sign_feed)
sign_in @user
end

test "should get access_code" do
@user.vital_sign_auths << VitalSignAuth.new(vital_sign_feed: @vital_sign_feed)
FakeWeb.register_uri(:get, "http://#{@vital_sign_feed.vital_sign_host.hostname}/authorize",
:body => '{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}')
get :access_code
assert_response :redirect
@user.reload
assert_equal "2YotnFZFEjr1zCsicMWpAA", @user.vital_sign_auths.first.access_token
end

end
53 changes: 53 additions & 0 deletions test/functional/vital_sign_hosts_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'test_helper'

class VitalSignHostsControllerTest < ActionController::TestCase
include Devise::TestHelpers

setup do
@user = FactoryGirl.create(:user)
@vital_sign_host = FactoryGirl.create(:vital_sign_host)
sign_in @user
end

test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:vital_sign_hosts)
end

test "should get new" do
get :new
assert_response :success
end

test "should create vital_sign_host" do
assert_difference('VitalSignHost.count') do
post :create, vital_sign_host: { client_id: @vital_sign_host.client_id, client_secret: @vital_sign_host.client_secret, hostname: @vital_sign_host.hostname }
end

assert_redirected_to vital_sign_host_path(assigns(:vital_sign_host))
end

test "should show vital_sign_host" do
get :show, id: @vital_sign_host
assert_response :success
end

test "should get edit" do
get :edit, id: @vital_sign_host
assert_response :success
end

test "should update vital_sign_host" do
put :update, id: @vital_sign_host, vital_sign_host: { client_id: @vital_sign_host.client_id, client_secret: @vital_sign_host.client_secret, hostname: @vital_sign_host.hostname }
assert_redirected_to vital_sign_host_path(assigns(:vital_sign_host))
end

test "should destroy vital_sign_host" do
assert_difference('VitalSignHost.count', -1) do
delete :destroy, id: @vital_sign_host
end

assert_redirected_to vital_sign_hosts_path
end
end
7 changes: 7 additions & 0 deletions test/unit/vital_sign_host_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'test_helper'

class VitalSignHostTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

0 comments on commit a118fb4

Please sign in to comment.