set created_by/at and modified_by/at attributes when saving objects
authorTom Clegg <tom@clinicalfuture.com>
Thu, 24 Jan 2013 19:27:36 +0000 (11:27 -0800)
committerTom Clegg <tom@clinicalfuture.com>
Thu, 24 Jan 2013 19:27:36 +0000 (11:27 -0800)
app/controllers/application_controller.rb
app/controllers/user_sessions_controller.rb
app/models/orvos_model.rb
config/initializers/current_api_client.rb [new file with mode: 0644]
lib/current_api_client.rb [new file with mode: 0644]

index 98b31a5f5ae2d92a9627515e5c4d18216a1e17ba..893472c64a936f1f08613aadeceb8c3bfd4d8b1f 100644 (file)
@@ -1,4 +1,6 @@
 class ApplicationController < ActionController::Base
+  include CurrentApiClient
+
   protect_from_forgery
   before_filter :uncamelcase_params_hash_keys
   around_filter :thread_with_auth_info, :except => [:render_error, :render_not_found]
@@ -48,9 +50,9 @@ class ApplicationController < ActionController::Base
 
   def index
     @objects ||= model_class.
-      joins("LEFT JOIN metadata permissions ON permissions.tail=#{table_name}.uuid AND permissions.head=#{model_class.sanitize Thread.current[:user_uuid]} AND permissions.metadata_class='permission' AND permissions.name='visible_to'").
+      joins("LEFT JOIN metadata permissions ON permissions.tail=#{table_name}.uuid AND permissions.head=#{model_class.sanitize current_user.uuid} AND permissions.metadata_class='permission' AND permissions.name='visible_to'").
       where("#{table_name}.created_by_user=? OR permissions.head IS NOT NULL",
-            Thread.current[:user_uuid])
+            current_user.uuid)
     if params[:where]
       where = params[:where]
       where = JSON.parse(where) if where.is_a?(String)
@@ -110,10 +112,6 @@ class ApplicationController < ActionController::Base
     show
   end
 
-  def current_user
-    Thread.current[:user]
-  end
-
   protected
 
   # Authentication
@@ -132,30 +130,35 @@ class ApplicationController < ActionController::Base
 
   def thread_with_auth_info
     begin
+      user = nil
+      api_client = nil
+      api_client_auth = nil
       if params[:api_token]
-        @api_client_auth = ApiClientAuthorization.
+        api_client_auth = ApiClientAuthorization.
           includes(:api_client, :user).
           where('api_token=?', params[:api_token]).
           first
-        if @api_client_auth
-          session[:user_id] = @api_client_auth.user.id
-          session[:user_uuid] = @api_client_auth.user.uuid
-          session[:api_client_uuid] = @api_client_auth.api_client.uuid
+        if api_client_auth
+          session[:user_id] = api_client_auth.user.id
+          session[:api_client_uuid] = api_client_auth.api_client.uuid
+          user = api_client_auth.user
+          api_client = api_client_auth.api_client
         end
+      elsif session[:user_id]
+        user = User.find(session[:user_id]) rescue nil
+        api_client = ApiClient.
+          where('uuid=?',session[:api_client_uuid]).
+          first rescue nil
       end
       Thread.current[:api_client_trusted] = session[:api_client_trusted]
       Thread.current[:api_client_ip_address] = remote_ip
-      Thread.current[:api_client_uuid] = session[:api_client_uuid]
-      Thread.current[:user_uuid] = session[:user_uuid]
-      Thread.current[:remote_ip] = remote_ip
-      Thread.current[:user] = User.find(session[:user_id]) rescue nil
+      Thread.current[:api_client] = api_client
+      Thread.current[:user] = user
       yield
     ensure
       Thread.current[:api_client_trusted] = nil
       Thread.current[:api_client_ip_address] = nil
       Thread.current[:api_client_uuid] = nil
-      Thread.current[:user_uuid] = nil
-      Thread.current[:remote_ip] = nil
       Thread.current[:user] = nil
     end
   end
@@ -228,7 +231,6 @@ class ApplicationController < ActionController::Base
     render json: @object_list
   end
 
-private
   def remote_ip
     # Caveat: this is highly dependent on the proxy setup. YMMV.
     if request.headers.has_key?('HTTP_X_REAL_IP') then
index 4b0df68e23983943e030069716d7fc70fd77eabc..22e4cbe4cec8f09a63cc2410fba65c22617ddc04 100644 (file)
@@ -40,7 +40,6 @@ class UserSessionsController < ApplicationController
 
     # Give the authenticated user a cookie for direct API access
     session[:user_id] = user.id
-    session[:user_uuid] = user.uuid
     session[:api_client_uuid] = nil
     session[:api_client_trusted] = true # full permission to see user's secrets
 
@@ -100,7 +99,7 @@ class UserSessionsController < ApplicationController
     api_client_auth = ApiClientAuthorization.
       new(user: user,
           api_client: api_client,
-          created_by_ip_address: Thread.current[:remote_ip])
+          created_by_ip_address: remote_ip)
     api_client_auth.save!
 
     if callback_url.index('?')
index 247ff50fc8a89244cc5f0c54430d7416350b05c3..e288ebf0d862684e58be52deb03d36480759e74a 100644 (file)
@@ -1,6 +1,17 @@
 class OrvosModel < ActiveRecord::Base
   self.abstract_class = true
 
+  include CurrentApiClient      # current_user, current_api_client, etc.
+
+  attr_protected :created_by_user
+  attr_protected :created_by_client
+  attr_protected :created_at
+  attr_protected :modified_by_user
+  attr_protected :modified_by_client
+  attr_protected :modified_at
+  before_create :initialize_created_by_fields
+  before_update :update_modified_by_fields
+
   def self.kind_class(kind)
     kind.match(/^orvos\#(.+?)(_list|List)?$/)[1].pluralize.classify.constantize rescue nil
   end
@@ -17,4 +28,23 @@ class OrvosModel < ActiveRecord::Base
       end
     end
   end
+
+  protected
+
+  def update_modified_by_fields
+    if self.changed?
+      self.modified_at = Time.now
+      self.modified_by_user = current_user.uuid
+      self.modified_by_client = current_api_client.uuid
+    end
+  end
+
+  def initialize_created_by_fields
+    self.created_at = Time.now
+    self.created_by_user = current_user.uuid
+    self.created_by_client = current_api_client.uuid
+    self.modified_at = Time.now
+    self.modified_by_user = current_user.uuid
+    self.modified_by_client = current_api_client.uuid
+  end
 end
diff --git a/config/initializers/current_api_client.rb b/config/initializers/current_api_client.rb
new file mode 100644 (file)
index 0000000..6680266
--- /dev/null
@@ -0,0 +1 @@
+require 'current_api_client'
diff --git a/lib/current_api_client.rb b/lib/current_api_client.rb
new file mode 100644 (file)
index 0000000..bf62b7f
--- /dev/null
@@ -0,0 +1,20 @@
+module CurrentApiClient
+  def current_user
+    Thread.current[:user]
+  end
+
+  def current_api_client
+    Thread.current[:api_client]
+  end
+
+  # Where is the client connecting from?
+  def current_api_client_ip_address
+    Thread.current[:api_client_ip_address]
+  end
+
+  # Is the current client permitted to perform ALL actions on behalf
+  # of the authenticated user?
+  def current_api_client_trusted
+    Thread.current[:api_client_trusted]
+  end
+end