Browse code

Setup token sessions

Cinan Rakosnik authored on 05/02/2013 at 23:11:12
Showing 18 changed files
1 1
old mode 100755
2 2
new mode 100644
... ...
@@ -5,4 +5,4 @@ You are allowed to:
5 5
 2. Remove generators
6 6
 3. Add installed generators
7 7
 To add new installed generators automatically delete this file and reload the project.
8
+--><GeneratorsGroup><Generator name="active_record:migration" /><Generator name="active_record:model" /><Generator name="active_record:observer" /><Generator name="active_record:session_migration" /><Generator name="assets" /><Generator name="coffee:assets" /><Generator name="controller" /><Generator name="erb:controller" /><Generator name="erb:mailer" /><Generator name="erb:scaffold" /><Generator name="generator" /><Generator name="helper" /><Generator name="integration_test" /><Generator name="jquery:install" /><Generator name="js:assets" /><Generator name="mailer" /><Generator name="migration" /><Generator name="model" /><Generator name="mongoid:config" /><Generator name="observer" /><Generator name="performance_test" /><Generator name="resource" /><Generator name="scaffold" /><Generator name="scaffold_controller" /><Generator name="session_migration" /><Generator name="task" /></GeneratorsGroup></Settings>
8 9
old mode 100755
9 10
new mode 100644
... ...
@@ -22,13 +22,18 @@ group :assets do
22 22
 end
23 23
 
24 24
 group :development, :test do
25
-  gem 'rspec-rails'
26
-  gem 'spork'
27 25
 end
28 26
 
29 27
 group :development do
30 28
 end
31 29
 
30
+group :test do
31
+	gem "minitest"
32
+	gem 'minitest-reporters', '>= 0.5.0'
33
+	gem 'test-unit'
34
+	gem 'timecop'
35
+end
36
+
32 37
 gem 'jquery-rails'
33 38
 gem "haml", "~> 3.1.7"
34 39
 gem "haml-rails", "~> 0.3.5"
... ...
@@ -28,6 +28,7 @@ GEM
28 28
     activesupport (3.2.11)
29 29
       i18n (~> 0.6)
30 30
       multi_json (~> 1.0)
31
+    ansi (1.4.3)
31 32
     arel (3.0.2)
32 33
     builder (3.0.4)
33 34
     capistrano (2.14.1)
... ...
@@ -48,7 +49,6 @@ GEM
48 48
       chunky_png (~> 1.2)
49 49
       fssm (>= 0.2.7)
50 50
       sass (~> 3.1)
51
-    diff-lcs (1.1.3)
52 51
     erubis (2.7.0)
53 52
     execjs (1.4.0)
54 53
       multi_json (~> 1.0)
... ...
@@ -59,6 +59,7 @@ GEM
59 59
       activesupport (>= 3.1, < 4.1)
60 60
       haml (~> 3.1)
61 61
       railties (>= 3.1, < 4.1)
62
+    hashie (1.2.0)
62 63
     highline (1.6.15)
63 64
     hike (1.2.1)
64 65
     i18n (0.6.1)
... ...
@@ -72,6 +73,12 @@ GEM
72 72
       mime-types (~> 1.16)
73 73
       treetop (~> 1.4.8)
74 74
     mime-types (1.20.1)
75
+    minitest (4.5.0)
76
+    minitest-reporters (0.14.7)
77
+      ansi
78
+      builder
79
+      minitest (>= 2.12, < 5.0)
80
+      powerbar
75 81
     mongoid (3.0.21)
76 82
       activemodel (~> 3.1)
77 83
       moped (~> 1.2)
... ...
@@ -88,6 +95,9 @@ GEM
88 88
       net-ssh (>= 1.99.1)
89 89
     origin (1.0.11)
90 90
     polyglot (0.3.3)
91
+    powerbar (1.0.11)
92
+      ansi (~> 1.4.0)
93
+      hashie (>= 1.1.0)
91 94
     rack (1.4.4)
92 95
     rack-cache (1.2)
93 96
       rack (>= 0.4)
... ...
@@ -113,30 +123,20 @@ GEM
113 113
     rake (10.0.3)
114 114
     rdoc (3.12)
115 115
       json (~> 1.4)
116
-    rspec-core (2.12.2)
117
-    rspec-expectations (2.12.1)
118
-      diff-lcs (~> 1.1.3)
119
-    rspec-mocks (2.12.2)
120
-    rspec-rails (2.12.2)
121
-      actionpack (>= 3.0)
122
-      activesupport (>= 3.0)
123
-      railties (>= 3.0)
124
-      rspec-core (~> 2.12.0)
125
-      rspec-expectations (~> 2.12.0)
126
-      rspec-mocks (~> 2.12.0)
127 116
     sass (3.2.5)
128 117
     sass-rails (3.2.6)
129 118
       railties (~> 3.2.0)
130 119
       sass (>= 3.1.10)
131 120
       tilt (~> 1.3)
132
-    spork (0.9.2)
133 121
     sprockets (2.2.2)
134 122
       hike (~> 1.2)
135 123
       multi_json (~> 1.0)
136 124
       rack (~> 1.0)
137 125
       tilt (~> 1.1, != 1.3.0)
126
+    test-unit (2.5.4)
138 127
     thor (0.17.0)
139 128
     tilt (1.3.3)
129
+    timecop (0.5.9.1)
140 130
     treetop (1.4.12)
141 131
       polyglot
142 132
       polyglot (>= 0.3.1)
... ...
@@ -156,10 +156,12 @@ DEPENDENCIES
156 156
   haml (~> 3.1.7)
157 157
   haml-rails (~> 0.3.5)
158 158
   jquery-rails
159
+  minitest
160
+  minitest-reporters (>= 0.5.0)
159 161
   mongoid (~> 3.0.20)
160 162
   rails (= 3.2.11)
161
-  rspec-rails
162 163
   sass-rails (~> 3.2.3)
163
-  spork
164
+  test-unit
165
+  timecop
164 166
   uglifier (>= 1.0.3)
165 167
   xmpp4r (~> 0.5)
166 168
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+# Place all the behaviors and hooks related to the matching controller here.
1
+# All this logic will automatically be available in application.js.
2
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
... ...
@@ -1,3 +1,34 @@
1 1
 class ApplicationController < ActionController::Base
2
-  protect_from_forgery
2
+  #protect_from_forgery
3
+
4
+	before_filter :require_login
5
+
6
+	def require_login
7
+		#if controller_name == 'sessions' && action_name == 'new'
8
+		#	true
9
+		#end
10
+
11
+		if authenticated?
12
+			create_new_authentification()
13
+		else
14
+			#create_new_authentification()
15
+			#Redirect to login page
16
+		end
17
+	end
18
+
19
+	protected
20
+
21
+	def authenticated?
22
+		!! Token.authenticate(session)
23
+	end
24
+
25
+	def create_new_authentification
26
+		Token.remove_old_session(session[:token])
27
+
28
+		session[:token] = Token.generate_token()
29
+		session[:created_at] = Time.now
30
+		session[:ip] = request.remote_ip
31
+
32
+		Token.save_session(session)
33
+	end
3 34
 end
4 35
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+class SessionsController < ApplicationController
1
+	def new
2
+
3
+	end
4
+
5
+	def create
6
+
7
+	end
8
+
9
+	def destroy
10
+		self.remove_old_session(session[:token])
11
+	end
12
+end
0 13
new file mode 100644
... ...
@@ -0,0 +1,2 @@
0
+module SessionsHelper
1
+end
0 2
new file mode 100644
... ...
@@ -0,0 +1,49 @@
0
+require 'ipaddr'
1
+
2
+class Token
3
+	include Mongoid::Document
4
+	include Mongoid::Timestamps::Created
5
+
6
+	index({ token: 1 })
7
+
8
+	field :token, type: String
9
+	field :date_expiring, type: DateTime
10
+	field :ip, type: Integer
11
+
12
+	def self.authenticate(session)
13
+		if session[:created_at] == nil
14
+			return false
15
+		end
16
+
17
+		matched_token = self.where(:token				=> session[:token],
18
+								   :ip					=> IPAddr.new(session[:ip]).to_i,
19
+								   :date_expiring.lte	=> session[:created_at] + Rails.application.config.max_lifetime,
20
+								   :created_at			=> session[:created_at]
21
+				).limit(1).first
22
+
23
+		matched_token
24
+	end
25
+
26
+	def self.save_session(session)
27
+		date_expiring = session[:created_at] + Rails.application.config.max_lifetime
28
+
29
+		self.create!(:token 		=> session[:token],
30
+					 :date_expiring	=> date_expiring,
31
+					 :created_at	=> session[:created_at],
32
+					 :ip			=> IPAddr.new(session[:ip]).to_i)
33
+	end
34
+
35
+	def self.remove_old_session(token)
36
+		self.delete_all(token: token)
37
+	end
38
+
39
+	private
40
+
41
+	def self.generate_token
42
+		begin
43
+			token = SecureRandom.urlsafe_base64
44
+		end while Token.where(token: token).exists?
45
+
46
+		token
47
+	end
48
+end
... ...
@@ -3,7 +3,7 @@
3 3
   %head
4 4
     %title= yield(:title) + " | App"
5 5
     %meta{:charset => "utf-8"}/
6
-    %link{ :href => "/css/screen.css", :media => "screen", :rel => "stylesheet" }
6
+    -#%link{ :href => "/css/screen.css", :media => "screen", :rel => "stylesheet" }
7 7
     = csrf_meta_tags
8 8
   %body
9 9
     = yield
10 10
\ No newline at end of file
11 11
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+- content_for(:title, 'Login')
1
+
2
+Hello
0 3
\ No newline at end of file
1 4
new file mode 100644
... ...
@@ -0,0 +1,2 @@
0
+# How long session will be remembered. 2 Weeks.
1
+Xmpp::Application.config.max_lifetime = 60 * 60 * 24 * 2
0 2
\ No newline at end of file
... ...
@@ -1,55 +1,8 @@
1 1
 Xmpp::Application.routes.draw do
2
-  # Sample of regular route:
3
-  #   match 'products/:id' => 'catalog#view'
4
-  # Keep in mind you can assign values other than :controller and :action
2
+	resources :sessions, only: [:new, :create, :destroy]
5 3
 
6
-  # Sample of named route:
7
-  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
8
-  # This route can be invoked with purchase_url(:id => product.id)
4
+  	root :to => 'sessions#new'
9 5
 
10
-  # Sample resource route (maps HTTP verbs to controller actions automatically):
11
-  #   resources :products
12
-
13
-  # Sample resource route with options:
14
-  #   resources :products do
15
-  #     member do
16
-  #       get 'short'
17
-  #       post 'toggle'
18
-  #     end
19
-  #
20
-  #     collection do
21
-  #       get 'sold'
22
-  #     end
23
-  #   end
24
-
25
-  # Sample resource route with sub-resources:
26
-  #   resources :products do
27
-  #     resources :comments, :sales
28
-  #     resource :seller
29
-  #   end
30
-
31
-  # Sample resource route with more complex sub-resources
32
-  #   resources :products do
33
-  #     resources :comments
34
-  #     resources :sales do
35
-  #       get 'recent', :on => :collection
36
-  #     end
37
-  #   end
38
-
39
-  # Sample resource route within a namespace:
40
-  #   namespace :admin do
41
-  #     # Directs /admin/products/* to Admin::ProductsController
42
-  #     # (app/controllers/admin/products_controller.rb)
43
-  #     resources :products
44
-  #   end
45
-
46
-  # You can have the root of your site routed with "root"
47
-  # just remember to delete public/index.html.
48
-  root :to => 'login#index'
49
-
50
-  # See how all your routes lay out with "rake routes"
51
-
52
-  # This is a legacy wild controller route that's not recommended for RESTful applications.
53
-  # Note: This route will make all actions in every controller accessible via GET requests.
54
-  # match ':controller(/:action(/:id))(.:format)'
6
+	match '/signin',  to: 'sessions#new'
7
+	match '/signout', to: 'sessions#destroy', via: :delete
55 8
 end
56 9
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
1
+
2
+one:
3
+  token: MyString
4
+  date_created: 
5
+  date_expiring: 
6
+  ip: 1
7
+
8
+two:
9
+  token: MyString
10
+  date_created: 
11
+  date_expiring: 
12
+  ip: 1
0 13
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+require 'test_helper'
1
+
2
+class SessionsControllerTest < ActionController::TestCase
3
+  # test "the truth" do
4
+  #   assert true
5
+  # end
6
+end
... ...
@@ -1,6 +1,8 @@
1 1
 ENV["RAILS_ENV"] = "test"
2 2
 require File.expand_path('../../config/environment', __FILE__)
3 3
 require 'rails/test_help'
4
+require 'minitest/autorun'
5
+require 'timecop'
4 6
 
5 7
 class ActiveSupport::TestCase
6 8
   # Add more helper methods to be used by all tests here...
7 9
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+require 'test_helper'
1
+
2
+class SessionsHelperTest < ActionView::TestCase
3
+end
0 4
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+require 'test_helper'
1
+require 'ipaddr'
2
+
3
+class TokenTest < ActiveSupport::TestCase
4
+
5
+	def setup
6
+		@frozen_time = Time.now
7
+	end
8
+
9
+	def teardown
10
+		Token.delete_all()
11
+	end
12
+
13
+	test "should authentificate" do
14
+		Timecop.freeze(@frozen_time) do
15
+			Token.save_session({token: "123", ip: "8.8.8.8", created_at: Time.now})
16
+			assert !! Token.authenticate({token: "123", created_at: Time.now, ip: "8.8.8.8"})
17
+		end
18
+	end
19
+
20
+	test "shouldnt auth with wrong token" do
21
+		Timecop.freeze(@frozen_time) do
22
+			Token.save_session({token: "123", ip: "8.8.8.100", created_at: @frozen_time})
23
+			assert_false !! Token.authenticate({token: "14423", created_at: @frozen_time, ip: "8.8.8.100"})
24
+		end
25
+	end
26
+
27
+	test "shouldnt auth with wrong time" do
28
+		Timecop.freeze(@frozen_time) do
29
+			Token.save_session({token: "123", ip: "8.1.1.1", created_at: @frozen_time})
30
+			assert_false !! Token.authenticate({token: "123", created_at: @frozen_time + Rails.application.config.max_lifetime + 10, ip: "8.1.1.1"})
31
+		end
32
+	end
33
+
34
+	test "shouldnt auth with wrong ip" do
35
+		Timecop.freeze(@frozen_time) do
36
+			Token.save_session({token: "123", ip: "8.1.1.1", created_at: @frozen_time})
37
+			assert_false !! Token.authenticate({token: "123", created_at: @frozen_time, ip: "8.1.1.100"})
38
+		end
39
+	end
40
+end