Browse Source

Removed not used logon_session feature. Added web socket authentication. Prepared browser finger print.

Martin Edenhofer 9 years ago
parent
commit
2760137eef

+ 26 - 0
app/assets/javascripts/app/lib/app_post/browser.coffee

@@ -47,6 +47,32 @@ class App.Browser
     # allow browser
     true
 
+  @fingerprint: ->
+    localStorage = window['localStorage']
+
+    # read from local storage
+    if localStorage
+      fingerprint = localStorage.getItem('fingerprint')
+    return fingerprint if fingerprint
+
+    # detect fingerprint
+    data = @detection()
+    resolution = "#{window.screen.availWidth}x#{window.screen.availHeight}/#{window.screen.pixelDepth}"
+    timezone = new Date().toString().match(/\s\(.+?\)$/)
+    hashCode = (s) ->
+      s.split('').reduce(
+        (a,b) ->
+          a=((a<<5)-a)+b.charCodeAt(0)
+          a&a
+        0
+      )
+    fingerprint = hashCode("#{data.browser.name}#{data.browser.major}#{data.os}#{resolution}#{timezone}")
+
+    # write to local storage
+    if localStorage
+      localStorage.setItem('fingerprint', fingerprint)
+    fingerprint
+
   @message: (data, version) ->
     new App.ControllerModal(
       head:     'Browser too old!'

+ 2 - 2
app/assets/javascripts/app/lib/app_post/websocket.js.coffee

@@ -115,8 +115,8 @@ class _webSocketSingleton extends App.Controller
     # logon websocket
     data =
       action: 'login'
-      session:
-        id: App.Session.get('id')
+      session_id: App.Config.get('session_id')
+      fingerprint: App.Browser.fingerprint()
     @send(data)
 
   spool: =>

+ 4 - 19
app/controllers/application_controller.rb

@@ -140,25 +140,6 @@ class ApplicationController < ActionController::Base
 
     error_message = 'authentication failed'
 
-    # check logon session
-    if params['logon_session']
-      logon_session = ActiveRecord::SessionStore::Session.where( session_id: params['logon_session'] ).first
-
-      # set logon session user to current user
-      if logon_session
-        userdata = User.find( logon_session.data[:user_id] )
-        current_user_set(userdata)
-
-        session[:persistent] = true
-
-        return {
-          auth: true
-        }
-      end
-
-      error_message = 'no valid session, user_id'
-    end
-
     # check sso
     sso_userdata = User.sso(params)
     if sso_userdata
@@ -296,10 +277,14 @@ class ApplicationController < ActionController::Base
       config['timezones'][ t.name ] = diff
     }
 
+    # remember if we can to swich back to user
     if session[:switched_from_user_id]
       config['switch_back_to_possible'] = true
     end
 
+    # remember session_id for websocket logon
+    config['session_id'] = session.id
+
     config
   end
 

+ 3 - 23
app/controllers/sessions_controller.rb

@@ -42,18 +42,6 @@ class SessionsController < ApplicationController
     # get models
     models = SessionHelper.models(user)
 
-    # check logon session
-    logon_session_key = nil
-    if params['logon_session']
-      logon_session_key = Digest::MD5.hexdigest( rand(999_999).to_s + Time.zone.now.to_s )
-      #      session = ActiveRecord::SessionStore::Session.create(
-      #        :session_id => logon_session_key,
-      #        :data => {
-      #          :user_id => user['id']
-      #        }
-      #      )
-    end
-
     # sessions created via this
     # controller are persistent
     session[:persistent] = true
@@ -62,10 +50,10 @@ class SessionsController < ApplicationController
     render  status: :created,
             json: {
               session: user,
+              config: config_frontend,
               models: models,
               collections: collections,
               assets: assets,
-              logon_session: logon_session_key,
             }
   end
 
@@ -78,14 +66,6 @@ class SessionsController < ApplicationController
       user_id = session[:user_id]
     end
 
-    # check logon session
-    if params['logon_session']
-      session = SessionHelper.get( params['logon_session'] )
-      if session
-        user_id = session.data[:user_id]
-      end
-    end
-
     if !user_id
       # get models
       models = SessionHelper.models()
@@ -96,7 +76,7 @@ class SessionsController < ApplicationController
         models: models,
         collections: {
           Locale.to_app_model => Locale.where( active: true )
-        }
+        },
       }
       return
     end
@@ -117,10 +97,10 @@ class SessionsController < ApplicationController
     # return current session
     render json: {
       session: user,
+      config: config_frontend,
       models: models,
       collections: collections,
       assets: assets,
-      config: config_frontend,
     }
   end
 

+ 2 - 2
lib/session_helper.rb

@@ -37,7 +37,7 @@ module SessionHelper
   end
 
   def self.get(id)
-    ActiveRecord::SessionStore::Session.where( id: id ).first
+    ActiveRecord::SessionStore::Session.find_by( id: id )
   end
 
   def self.list(limit = 10_000)
@@ -45,7 +45,7 @@ module SessionHelper
   end
 
   def self.destroy(id)
-    session = ActiveRecord::SessionStore::Session.where( id: id ).first
+    session = ActiveRecord::SessionStore::Session.find_by( id: id )
     return if !session
     session.destroy
   end

+ 23 - 4
script/websocket-server.rb

@@ -12,6 +12,12 @@ require 'sessions'
 require 'optparse'
 require 'daemons'
 
+# load rails env
+dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+Dir.chdir dir
+RAILS_ENV = ENV['RAILS_ENV'] || 'development'
+require File.join(dir, 'config', 'environment')
+
 # Look for -o with argument, and -I and -D boolean arguments
 @options = {
   p: 6042,
@@ -176,10 +182,23 @@ EventMachine.run {
 
       # get session
       if data['action'] == 'login'
-        @clients[client_id][:session] = data['session']
-        Sessions.create( client_id, data['session'], { type: 'websocket' } )
 
-        # remember ping, send pong back
+        # get user_id
+        if data['session_id']
+          session = ActiveRecord::SessionStore::Session.find_by( session_id: data['session_id'] )
+        end
+
+        if session && session.data && session.data['user_id']
+          new_session_data = { 'id' => session.data['user_id'] }
+        else
+          new_session_data = {}
+        end
+
+        @clients[client_id][:session] = new_session_data
+
+        Sessions.create( client_id, new_session_data, { type: 'websocket' } )
+
+      # remember ping, send pong back
       elsif data['action'] == 'ping'
         Sessions.touch(client_id)
         @clients[client_id][:last_ping] = Time.now.utc.to_i
@@ -188,7 +207,7 @@ EventMachine.run {
         }
         websocket_send(client_id, message)
 
-        # broadcast
+      # broadcast
       elsif data['action'] == 'broadcast'
 
         # list all current clients