authentication-service 0.0.1.a1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rvmrc +83 -0
- data/Gemfile +4 -0
- data/README +0 -0
- data/Rakefile +1 -0
- data/authentication-service.gemspec +22 -0
- data/lib/authentication-service/account.rb +17 -0
- data/lib/authentication-service/base.rb +41 -0
- data/lib/authentication-service/persistance/accounts-repository.rb +22 -0
- data/lib/authentication-service/persistance/sessions-repository.rb +37 -0
- data/lib/authentication-service/persistance.rb +19 -0
- data/lib/authentication-service/rails/sessions-controller-actions.rb +38 -0
- data/lib/authentication-service/rails.rb +89 -0
- data/lib/authentication-service/session.rb +32 -0
- data/lib/authentication-service/version.rb +3 -0
- data/lib/authentication-service.rb +9 -0
- data/spec/lib/account_spec.rb +10 -0
- data/spec/lib/base_spec.rb +106 -0
- data/spec/lib/persistance/accounts_repository_spec.rb +52 -0
- data/spec/lib/persistance/sessions_repository_spec.rb +93 -0
- data/spec/lib/persistance_spec.rb +43 -0
- data/spec/lib/rails_sessions_controller_actions_spec.rb +169 -0
- data/spec/lib/rails_spec.rb +207 -0
- data/spec/lib/session_spec.rb +22 -0
- data/spec/spec_helper.rb +23 -0
- metadata +91 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
+
# Only full ruby name is supported here, for short names use:
|
8
|
+
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
+
environment_id="ruby-1.9.3-p0@auth-svc"
|
10
|
+
|
11
|
+
#
|
12
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
13
|
+
#
|
14
|
+
# rvmrc_rvm_version="1.10.2" # 1.10.1 seams as a safe start
|
15
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
16
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
17
|
+
# return 1
|
18
|
+
# }
|
19
|
+
#
|
20
|
+
|
21
|
+
#
|
22
|
+
# Uncomment following line if you want options to be set only for given project.
|
23
|
+
#
|
24
|
+
# PROJECT_JRUBY_OPTS=( --1.9 )
|
25
|
+
#
|
26
|
+
# The variable PROJECT_JRUBY_OPTS requires the following to be run in shell:
|
27
|
+
#
|
28
|
+
# chmod +x ${rvm_path}/hooks/after_use_jruby_opts
|
29
|
+
#
|
30
|
+
|
31
|
+
#
|
32
|
+
# First we attempt to load the desired environment directly from the environment
|
33
|
+
# file. This is very fast and efficient compared to running through the entire
|
34
|
+
# CLI and selector. If you want feedback on which environment was used then
|
35
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
36
|
+
#
|
37
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
38
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
39
|
+
then
|
40
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
41
|
+
|
42
|
+
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
43
|
+
then
|
44
|
+
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
45
|
+
fi
|
46
|
+
else
|
47
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
48
|
+
if ! rvm --create "$environment_id"
|
49
|
+
then
|
50
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
51
|
+
return 1
|
52
|
+
fi
|
53
|
+
fi
|
54
|
+
|
55
|
+
#
|
56
|
+
# If you use an RVM gemset file to install a list of gems (*.gems), you can have
|
57
|
+
# it be automatically loaded. Uncomment the following and adjust the filename if
|
58
|
+
# necessary.
|
59
|
+
#
|
60
|
+
# filename=".gems"
|
61
|
+
# if [[ -s "$filename" ]]
|
62
|
+
# then
|
63
|
+
# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
|
64
|
+
# fi
|
65
|
+
|
66
|
+
# If you use bundler, this might be useful to you:
|
67
|
+
# if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
|
68
|
+
# then
|
69
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
70
|
+
# gem install bundler
|
71
|
+
# fi
|
72
|
+
# if [[ -s Gemfile ]] && command -v bundle
|
73
|
+
# then
|
74
|
+
# bundle install
|
75
|
+
# fi
|
76
|
+
|
77
|
+
if [[ $- == *i* ]] # check for interactive shells
|
78
|
+
then
|
79
|
+
echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
80
|
+
else
|
81
|
+
echo "Using: $GEM_HOME" # don't use colors in interactive shells
|
82
|
+
fi
|
83
|
+
|
data/Gemfile
ADDED
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "authentication-service/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "authentication-service"
|
7
|
+
s.version = AuthenticationService::VERSION
|
8
|
+
s.authors = ["Evgeny Myasishchev"]
|
9
|
+
s.email = ["evgeny.myasishchev@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Authentication service for Rails (and not only)}
|
12
|
+
s.description = %q{Provides authentication related stuff.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "authentication-service"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "rspec"
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'digest/sha2'
|
2
|
+
|
3
|
+
class AuthenticationService::Account
|
4
|
+
attr_reader :account_id
|
5
|
+
attr_accessor :email, :password_hash
|
6
|
+
|
7
|
+
def initialize(account_id, email, password_hash)
|
8
|
+
@account_id, @email, @password_hash = account_id, email, password_hash
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def hash_for_password(password)
|
14
|
+
Digest::SHA512.hexdigest(password)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class AuthenticationService::Base
|
2
|
+
attr_reader :accounts_repository, :sessions_repository
|
3
|
+
|
4
|
+
def initialize(accounts_repository, sessions_repository)
|
5
|
+
@accounts_repository = accounts_repository
|
6
|
+
@sessions_repository = sessions_repository
|
7
|
+
end
|
8
|
+
|
9
|
+
def register_account(email, password)
|
10
|
+
accounts_repository.create(email, password)
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Returns Session instance if it exists and is valid
|
15
|
+
#
|
16
|
+
def authenticate_by_session_id(session_id, ip_address)
|
17
|
+
session = sessions_repository.find_by_session_id(session_id)
|
18
|
+
return nil unless session
|
19
|
+
return nil unless session.ip_address == ip_address
|
20
|
+
sessions_repository.touch session.session_id
|
21
|
+
return session
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Validates login/password and returns new Session instance
|
26
|
+
# Login is email
|
27
|
+
#
|
28
|
+
def authenticate_by_login(login, password, ip_address)
|
29
|
+
account = accounts_repository.find_by_email(login)
|
30
|
+
return nil unless account
|
31
|
+
|
32
|
+
password_hash = AuthenticationService::Account.hash_for_password(password)
|
33
|
+
return nil unless account.password_hash == password_hash
|
34
|
+
|
35
|
+
sessions_repository.create AuthenticationService::Session.create_new(account, ip_address)
|
36
|
+
end
|
37
|
+
|
38
|
+
def sign_out(session)
|
39
|
+
sessions_repository.destroy(session)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module AuthenticationService::Persistance
|
2
|
+
class AccountsRepository
|
3
|
+
include AuthenticationService::Persistance::ModelHelpers
|
4
|
+
|
5
|
+
attr_reader :model_class
|
6
|
+
|
7
|
+
def initialize(model_class)
|
8
|
+
@model_class = model_class
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(email, password)
|
12
|
+
rec = @model_class.create! :email => email, :password_hash => AuthenticationService::Account.hash_for_password(password)
|
13
|
+
to_account_model rec
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_by_email(email)
|
17
|
+
rec = @model_class.find_by_email(email)
|
18
|
+
return nil unless rec
|
19
|
+
to_account_model rec
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module AuthenticationService::Persistance
|
2
|
+
class SessionsRepository
|
3
|
+
include AuthenticationService::Persistance::ModelHelpers
|
4
|
+
|
5
|
+
attr_reader :model_class
|
6
|
+
|
7
|
+
def initialize(model_class)
|
8
|
+
@model_class = model_class
|
9
|
+
end
|
10
|
+
|
11
|
+
def find_by_session_id(session_id)
|
12
|
+
rec = @model_class.includes(:account).find_by_session_id(session_id)
|
13
|
+
return nil unless rec
|
14
|
+
return to_session_model rec
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(session)
|
18
|
+
@model_class.create! :session_id => session.session_id,
|
19
|
+
:account_id => session.account.account_id,
|
20
|
+
:ip_address => session.ip_address,
|
21
|
+
:created_at => session.created_at,
|
22
|
+
:updated_at => session.last_time_used_at
|
23
|
+
session
|
24
|
+
end
|
25
|
+
|
26
|
+
def touch(session_id)
|
27
|
+
rec = @model_class.find_by_session_id(session_id)
|
28
|
+
rec.touch
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy(session)
|
32
|
+
rec = @model_class.find_by_session_id(session.session_id)
|
33
|
+
rec.destroy
|
34
|
+
session
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module AuthenticationService::Persistance
|
2
|
+
autoload :AccountsRepository, 'authentication-service/persistance/accounts-repository'
|
3
|
+
autoload :SessionsRepository, 'authentication-service/persistance/sessions-repository'
|
4
|
+
|
5
|
+
|
6
|
+
module ModelHelpers
|
7
|
+
def to_session_model(session_record)
|
8
|
+
AuthenticationService::Session.new(session_record.session_id,
|
9
|
+
to_account_model(session_record.account),
|
10
|
+
session_record.ip_address,
|
11
|
+
session_record.created_at,
|
12
|
+
session_record.updated_at)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_account_model(account_record)
|
16
|
+
AuthenticationService::Account.new account_record.id, account_record.email, account_record.password_hash
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module AuthenticationService::Rails::SessionsControllerActions
|
2
|
+
def self.included(base)
|
3
|
+
base.before_filter :authenticate, :only => :destroy
|
4
|
+
end
|
5
|
+
|
6
|
+
def new
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
authenticated_session = authentication_service.authenticate_by_login(params[:login], params[:password], request.remote_ip)
|
11
|
+
if authenticated_session
|
12
|
+
session[:authenticated_session_id] = authenticated_session.session_id
|
13
|
+
redirect_back
|
14
|
+
else
|
15
|
+
respond_to do |format|
|
16
|
+
format.html {
|
17
|
+
render :action => :new, :status => :unauthorized
|
18
|
+
}
|
19
|
+
format.json {
|
20
|
+
render :nothing => true, :status => :unauthorized
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def destroy
|
27
|
+
authentication_service.sign_out(current_session)
|
28
|
+
reset_session
|
29
|
+
respond_to do |format|
|
30
|
+
format.html {
|
31
|
+
redirect_to(sign_in_url)
|
32
|
+
}
|
33
|
+
format.json {
|
34
|
+
render :json => {'navigate-to' => sign_in_url}
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module AuthenticationService::Rails
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
class OptionsStore
|
9
|
+
class << self
|
10
|
+
attr_accessor :account_class, :session_class
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def account_class
|
15
|
+
OptionsStore.account_class
|
16
|
+
end
|
17
|
+
|
18
|
+
def session_class
|
19
|
+
OptionsStore.session_class
|
20
|
+
end
|
21
|
+
|
22
|
+
def authentication_service(options)
|
23
|
+
options = {
|
24
|
+
:account => nil,
|
25
|
+
:session => nil
|
26
|
+
}.merge(options)
|
27
|
+
|
28
|
+
raise "Account persistance model class not assigned" unless options[:account]
|
29
|
+
raise "Session persistance model class not assigned" unless options[:session]
|
30
|
+
|
31
|
+
OptionsStore.account_class = options[:account]
|
32
|
+
OptionsStore.session_class = options[:session]
|
33
|
+
end
|
34
|
+
|
35
|
+
def behave_as_sessins_controller
|
36
|
+
self.send(:include, AuthenticationService::Rails::SessionsControllerActions)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
autoload :SessionsControllerActions, 'authentication-service/rails/sessions-controller-actions'
|
41
|
+
|
42
|
+
attr_accessor :current_session
|
43
|
+
|
44
|
+
def authenticated?
|
45
|
+
!current_session.blank?
|
46
|
+
end
|
47
|
+
|
48
|
+
def authenticate
|
49
|
+
authenticate_from_session if session[:authenticated_session_id]
|
50
|
+
redirect_not_authenticated unless authenticated?
|
51
|
+
end
|
52
|
+
|
53
|
+
def authentication_service
|
54
|
+
@authentication_service ||= begin
|
55
|
+
raise "Authentication service not configured. Please use authentication_service to configure it." unless self.class.account_class
|
56
|
+
raise "Authentication service not configured. Please use authentication_service to configure it." unless self.class.session_class
|
57
|
+
accounts_repository = AuthenticationService::Persistance::AccountsRepository.new(self.class.account_class)
|
58
|
+
sessions_repository = AuthenticationService::Persistance::SessionsRepository.new(self.class.session_class)
|
59
|
+
AuthenticationService::Base.new(accounts_repository, sessions_repository)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def authentication_service=(value)
|
64
|
+
@authentication_service = value
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
def redirect_not_authenticated
|
69
|
+
session[:return_to] = request.fullpath
|
70
|
+
redirect_to sign_in_url
|
71
|
+
end
|
72
|
+
|
73
|
+
def redirect_back
|
74
|
+
respond_to do |format|
|
75
|
+
format.html {
|
76
|
+
redirect_to(session[:return_to] || root_url)
|
77
|
+
}
|
78
|
+
format.json {
|
79
|
+
render :json => {'navigate-to' => (session[:return_to] || root_url)}
|
80
|
+
}
|
81
|
+
end
|
82
|
+
session[:return_to] = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
def authenticate_from_session
|
87
|
+
self.current_session = authentication_service.authenticate_by_session_id(session[:authenticated_session_id], request.remote_ip)
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
class AuthenticationService::Session
|
4
|
+
attr_reader :session_id
|
5
|
+
|
6
|
+
#Account instance of this session
|
7
|
+
attr_reader :account
|
8
|
+
|
9
|
+
#Ip address of the client that has issued the session
|
10
|
+
attr_reader :ip_address
|
11
|
+
|
12
|
+
#Date/Time when session has been started
|
13
|
+
attr_reader :created_at
|
14
|
+
|
15
|
+
#Date/Time when the session has been used last time
|
16
|
+
attr_reader :last_time_used_at
|
17
|
+
|
18
|
+
def initialize(session_id, account, ip_address, created_at, last_time_used_at)
|
19
|
+
@session_id, @account, @ip_address, @created_at, @last_time_used_at = session_id, account, ip_address, created_at, last_time_used_at
|
20
|
+
end
|
21
|
+
|
22
|
+
# Make sure the session has not expired and ip_address is the same as originally issued
|
23
|
+
def is_valid?(ip_address)
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def create_new(account, ip_address)
|
29
|
+
new(SecureRandom.hex(32), account, ip_address, DateTime.now, DateTime.now)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require "authentication-service/version"
|
2
|
+
|
3
|
+
module AuthenticationService
|
4
|
+
autoload :Account, 'authentication-service/account'
|
5
|
+
autoload :Base, 'authentication-service/base'
|
6
|
+
autoload :Persistance, 'authentication-service/persistance'
|
7
|
+
autoload :Rails, 'authentication-service/rails'
|
8
|
+
autoload :Session, 'authentication-service/session'
|
9
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Account do
|
4
|
+
describe "hash_for_password" do
|
5
|
+
it "should use SHA512 as hashing method" do
|
6
|
+
sha512_hash = Digest::SHA512.hexdigest('some-password')
|
7
|
+
Account.hash_for_password('some-password').should eql sha512_hash
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AuthenticationService::Base do
|
4
|
+
before(:each) do
|
5
|
+
@sessions_repository = mock(:sessions_repository)
|
6
|
+
@accounts_repository = mock(:accounts_repository)
|
7
|
+
@authentication_service = AuthenticationService::Base.new(@accounts_repository, @sessions_repository)
|
8
|
+
|
9
|
+
@account = Account.new(10, "mail@domain.com", "some-password-hash")
|
10
|
+
@session = Session.new("session-id", @account, "127.0.0.1", nil, nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "register_account" do
|
14
|
+
it "should use accounts repository to create new account" do
|
15
|
+
account = Account.new(10, "mail@domain.com", "some-password-hash")
|
16
|
+
@accounts_repository.should_receive(:create).with("mail@domain.com", "some-password").and_return(account)
|
17
|
+
|
18
|
+
@authentication_service.register_account "mail@domain.com", "some-password"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return created account instance" do
|
22
|
+
account = Account.new(10, "mail@domain.com", "some-password-hash")
|
23
|
+
@accounts_repository.stub(:create).and_return(account)
|
24
|
+
|
25
|
+
@authentication_service.register_account("mail@domain.com", "some-password").should be account
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "authenticate_by_session_id" do
|
30
|
+
before(:each) do
|
31
|
+
@sessions_repository.stub(:find_by_session_id) { @session }
|
32
|
+
@sessions_repository.stub(:touch)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should use sessions repository to find stored sessions" do
|
36
|
+
@sessions_repository.should_receive(:find_by_session_id).with("session-id").and_return(@session)
|
37
|
+
@authentication_service.authenticate_by_session_id("session-id", "127.0.0.1")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return nil if session does not exist" do
|
41
|
+
@sessions_repository.stub(:find_by_session_id) { nil }
|
42
|
+
@authentication_service.authenticate_by_session_id("session-id", "127.0.0.1").should be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return the session if ip_address is the same as initial" do
|
46
|
+
@authentication_service.authenticate_by_session_id("session-id", "127.0.0.1").should be @session
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return nil if ip_address is different from initial" do
|
50
|
+
@authentication_service.authenticate_by_session_id("session-id", "127.0.0.2").should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should touch session so last_time_used_at gets updated" do
|
54
|
+
@sessions_repository.should_receive(:touch).with("session-id")
|
55
|
+
@authentication_service.authenticate_by_session_id("session-id", "127.0.0.1")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "authenticate_by_login" do
|
60
|
+
before(:each) do
|
61
|
+
@accounts_repository.stub(:find_by_email) { @account }
|
62
|
+
Session.stub(:create_new) { @session }
|
63
|
+
@sessions_repository.stub(:create) { @session }
|
64
|
+
Account.stub(:hash_for_password) { "some-password-hash" }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should use accounts repository to obtain accounts" do
|
68
|
+
@accounts_repository.should_receive(:find_by_email).with("mail@domain.com").and_return(@account)
|
69
|
+
@authentication_service.authenticate_by_login("mail@domain.com", "some-password", "127.0.0.1")
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "account is found and password is valid" do
|
73
|
+
|
74
|
+
it "should return new session instance" do
|
75
|
+
@authentication_service.authenticate_by_login("mail@domain.com", "some-password", "127.0.0.1").should be @session
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should create new session using sessions repository" do
|
79
|
+
@sessions_repository.should_receive(:create).with(@session).and_return(@session)
|
80
|
+
@authentication_service.authenticate_by_login("mail@domain.com", "some-password", "127.0.0.1")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return nil if account not found" do
|
85
|
+
@accounts_repository.stub(:find_by_email) { nil }
|
86
|
+
@authentication_service.authenticate_by_login("mail@domain.com", "some-password", "127.0.0.1").should be_nil
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return nil if account is found but password is invalid" do
|
90
|
+
Account.stub(:hash_for_password) { "invalid-password-hash" }
|
91
|
+
@authentication_service.authenticate_by_login("mail@domain.com", "some-password", "127.0.0.1").should be_nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "sign_out" do
|
96
|
+
it "should destroy the session using repository" do
|
97
|
+
@sessions_repository.should_receive(:destroy).with(@session).and_return(@session)
|
98
|
+
@authentication_service.sign_out(@session)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return session object" do
|
102
|
+
@sessions_repository.stub(:destroy) {@session}
|
103
|
+
@authentication_service.sign_out(@session).should be @session
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AuthenticationService::Persistance::AccountsRepository do
|
4
|
+
before(:each) do
|
5
|
+
@model_class = mock(:account_model_class)
|
6
|
+
@repository = AuthenticationService::Persistance::AccountsRepository.new @model_class
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "create" do
|
10
|
+
it "should create corresponding database record" do
|
11
|
+
password_hash = AuthenticationService::Account.hash_for_password("some-password")
|
12
|
+
@model_class.should_receive(:create!).
|
13
|
+
with(:email => "mail@domain.com", :password_hash => password_hash).
|
14
|
+
and_return(mock(:account_rec, :id => 999, :email => "mail@domain.com", :password_hash => password_hash))
|
15
|
+
@repository.create "mail@domain.com", "some-password"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "return Account instance" do
|
19
|
+
password_hash = AuthenticationService::Account.hash_for_password("some-password")
|
20
|
+
@model_class.stub(:create!).
|
21
|
+
and_return(mock(:account_rec, :id => 999, :email => "mail@domain.com", :password_hash => password_hash))
|
22
|
+
account = @repository.create "mail@domain.com", "some-password"
|
23
|
+
account.should be_instance_of AuthenticationService::Account
|
24
|
+
account.account_id.should eql 999
|
25
|
+
account.email.should eql "mail@domain.com"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should hash password" do
|
29
|
+
AuthenticationService::Account.should_receive(:hash_for_password).with("some-password").and_return("hashed-password")
|
30
|
+
@model_class.stub(:create!).
|
31
|
+
and_return(mock(:account_rec, :id => 999, :email => "mail@domain.com", :password_hash => "hashed-password"))
|
32
|
+
account = @repository.create "mail@domain.com", "some-password"
|
33
|
+
account.password_hash.should eql "hashed-password"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "find_by_email" do
|
38
|
+
it "should return corresponding database record searching by email" do
|
39
|
+
rec = mock :account_rec, :id => 999, :email => "mail@domain.com", :password_hash => "some-hash"
|
40
|
+
@model_class.should_receive(:find_by_email).with("mail@domain.com").and_return(rec)
|
41
|
+
|
42
|
+
account = @repository.find_by_email rec.email
|
43
|
+
account.account_id.should eql rec.id
|
44
|
+
account.password_hash.should eql rec.password_hash
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return nil if no such account" do
|
48
|
+
@model_class.should_receive(:find_by_email).with("unknown-mail@domain.com").and_return(nil)
|
49
|
+
@repository.find_by_email("unknown-mail@domain.com").should be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AuthenticationService::Persistance::SessionsRepository do
|
4
|
+
include AuthenticationService::Persistance::ModelHelpers
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@model_class = mock(:session_model_class)
|
8
|
+
@repository = AuthenticationService::Persistance::SessionsRepository.new(@model_class)
|
9
|
+
@account_rec = mock :account_rec, :id => 999, :email => "mail@domain.com", :password_hash => "password-hash"
|
10
|
+
@session_rec = mock :session_rec,
|
11
|
+
:id => 555,
|
12
|
+
:session_id => "unique-session-id",
|
13
|
+
:account_id => @account_rec.id,
|
14
|
+
:account => @account_rec,
|
15
|
+
:ip_address => "127.0.0.2",
|
16
|
+
:created_at => DateTime.now,
|
17
|
+
:updated_at => DateTime.now
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "find_by_session_id" do
|
21
|
+
before(:each) do
|
22
|
+
@model_class.stub(:includes) { @model_class }
|
23
|
+
@model_class.stub(:find_by_session_id) { @session_rec }
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return corresponding session instance" do
|
27
|
+
@model_class.should_receive(:includes).with(:account) { @model_class }
|
28
|
+
@model_class.should_receive(:find_by_session_id).with("unique-session-id") { @session_rec }
|
29
|
+
|
30
|
+
session = @repository.find_by_session_id "unique-session-id"
|
31
|
+
session.should be_instance_of AuthenticationService::Session
|
32
|
+
session.ip_address.should eql "127.0.0.2"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return nil for not existing session_id" do
|
36
|
+
@model_class.stub(:find_by_session_id) { nil }
|
37
|
+
@repository.find_by_session_id("unknown-session-id").should be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should assign corresponding account" do
|
41
|
+
session = @repository.find_by_session_id "unique-session-id"
|
42
|
+
session.account.should_not be_nil
|
43
|
+
session.account.should be_instance_of AuthenticationService::Account
|
44
|
+
session.account.account_id.should eql @account_rec.id
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "create" do
|
49
|
+
it "should create corresponding database record" do
|
50
|
+
session = AuthenticationService::Session.create_new to_account_model(@account_rec), "127.0.0.1"
|
51
|
+
@model_class.should_receive(:create!).with(:session_id => session.session_id,
|
52
|
+
:account_id => session.account.account_id,
|
53
|
+
:ip_address => session.ip_address,
|
54
|
+
:created_at => session.created_at,
|
55
|
+
:updated_at => session.last_time_used_at)
|
56
|
+
|
57
|
+
@repository.create session
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return created session instance" do
|
61
|
+
new_session = AuthenticationService::Session.create_new to_account_model(@account_rec), "127.0.0.1"
|
62
|
+
@model_class.stub(:create!)
|
63
|
+
session = @repository.create new_session
|
64
|
+
session.should be(new_session)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "touch" do
|
69
|
+
it "should set updated_at date to now" do
|
70
|
+
@model_class.should_receive(:find_by_session_id).with(@session_rec.session_id).and_return(@session_rec)
|
71
|
+
@session_rec.should_receive :touch
|
72
|
+
@repository.touch @session_rec.session_id
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "destroy" do
|
77
|
+
before(:each) do
|
78
|
+
@session = to_session_model(@session_rec)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should destroy sessions record" do
|
82
|
+
@model_class.should_receive(:find_by_session_id).with(@session_rec.session_id).and_return(@session_rec)
|
83
|
+
@session_rec.should_receive(:destroy)
|
84
|
+
@repository.destroy(@session)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return sessions model" do
|
88
|
+
@model_class.stub(:find_by_session_id).and_return(@session_rec)
|
89
|
+
@session_rec.stub(:destroy)
|
90
|
+
@repository.destroy(@session).should be @session
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AuthenticationService::Persistance do
|
4
|
+
describe AuthenticationService::Persistance::ModelHelpers do
|
5
|
+
include AuthenticationService::Persistance::ModelHelpers
|
6
|
+
|
7
|
+
describe "to_account_model" do
|
8
|
+
it "should create new model instance" do
|
9
|
+
rec = mock :account, :id => 999, :email => "mail@domain.com", :password_hash => "password-hash"
|
10
|
+
account = to_account_model(rec)
|
11
|
+
account.account_id.should eql rec.id
|
12
|
+
account.email.should eql rec.email
|
13
|
+
account.password_hash.should eql rec.password_hash
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "to_session_model" do
|
18
|
+
before(:each) do
|
19
|
+
@account = mock :account, :id => 999, :email => "mail@domain.com", :password_hash => "password-hash"
|
20
|
+
@session = mock :session, :id => 998, :session_id => "some-session-id",
|
21
|
+
:account => @account,
|
22
|
+
:ip_address => "127.0.0.3",
|
23
|
+
:created_at => DateTime.now - 3,
|
24
|
+
:updated_at => DateTime.now - 2
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return session model with corresponding properties assigned" do
|
28
|
+
model = to_session_model(@session)
|
29
|
+
model.should be_instance_of(AuthenticationService::Session)
|
30
|
+
model.session_id.should eql @session.session_id
|
31
|
+
model.ip_address.should eql @session.ip_address
|
32
|
+
model.created_at.should eql @session.created_at
|
33
|
+
model.last_time_used_at.should eql @session.updated_at
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should also assign account" do
|
37
|
+
model = to_session_model(@session)
|
38
|
+
model.account.should be_instance_of AuthenticationService::Account
|
39
|
+
model.account.email.should eql "mail@domain.com"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class RailsSessionsControllerActionsSpecController
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_accessor :before_filter_args
|
7
|
+
def before_filter(sym, options)
|
8
|
+
@before_filter_args = {
|
9
|
+
:sym => sym,
|
10
|
+
:options => options
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
include AuthenticationService::Rails::SessionsControllerActions
|
16
|
+
|
17
|
+
attr_reader :session
|
18
|
+
attr_accessor :authentication_service, :current_session, :request, :params
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@session = {}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe RailsSessionsControllerActionsSpecController do
|
26
|
+
|
27
|
+
before(:each) do
|
28
|
+
@session = mock(:session)
|
29
|
+
@authentication_service = mock(:authentication_service)
|
30
|
+
@controller = RailsSessionsControllerActionsSpecController.new
|
31
|
+
@controller.request = mock(:request)
|
32
|
+
@controller.authentication_service = @authentication_service
|
33
|
+
|
34
|
+
@controller.stub(:redirect_back)
|
35
|
+
@controller.request.stub("remote_ip") { "localhost" }
|
36
|
+
@session.stub(:session_id) { "some-session-id" }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "module included" do
|
40
|
+
it "should define filter :authenticate for destroy action" do
|
41
|
+
@controller.class.before_filter_args[:sym].should eql :authenticate
|
42
|
+
@controller.class.before_filter_args[:options][:only].should eql :destroy
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "new" do
|
47
|
+
it "should do nothing" do
|
48
|
+
@controller.new
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "create" do
|
53
|
+
describe "authentication successful" do
|
54
|
+
it "uses authentication_service to create new session" do
|
55
|
+
@authentication_service.should_receive(:authenticate_by_login).with("admin", "password", "localhost").and_return(@session)
|
56
|
+
|
57
|
+
@controller.params = {
|
58
|
+
:login => "admin",
|
59
|
+
:password => "password"
|
60
|
+
}
|
61
|
+
@controller.create
|
62
|
+
end
|
63
|
+
|
64
|
+
it "remembers new session_id in session" do
|
65
|
+
@authentication_service.stub(:authenticate_by_login).and_return(@session)
|
66
|
+
|
67
|
+
@controller.params = {
|
68
|
+
:login => "admin",
|
69
|
+
:password => "password"
|
70
|
+
}
|
71
|
+
@controller.create
|
72
|
+
|
73
|
+
@controller.session[:authenticated_session_id].should eql "some-session-id"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "redirects redirect_back" do
|
77
|
+
@authentication_service.stub(:authenticate_by_login).and_return(@session)
|
78
|
+
|
79
|
+
@controller.should_receive :redirect_back
|
80
|
+
|
81
|
+
@controller.params = {
|
82
|
+
:login => "admin",
|
83
|
+
:password => "password"
|
84
|
+
}
|
85
|
+
@controller.create
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "authentication failed" do
|
90
|
+
before(:each) do
|
91
|
+
@authentication_service.stub(:authenticate_by_login).and_return(nil)
|
92
|
+
@format = mock(:format)
|
93
|
+
@format.stub(:json)
|
94
|
+
@format.stub(:html)
|
95
|
+
@controller.should_receive(:respond_to) do |&block| block.call(@format) end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "for html format" do
|
99
|
+
it "should render :new and return unauthorized status" do
|
100
|
+
@format.should_receive(:html) do |&block| block.call end
|
101
|
+
|
102
|
+
@controller.should_receive(:render).with(:action => :new, :status => :unauthorized)
|
103
|
+
|
104
|
+
@controller.params = {
|
105
|
+
:login => "admin",
|
106
|
+
:password => "password"
|
107
|
+
}
|
108
|
+
@controller.create
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "for json format" do
|
113
|
+
it "should render :nothing and return unauthorized status" do
|
114
|
+
@format.should_receive(:json) do |&block| block.call end
|
115
|
+
|
116
|
+
@controller.should_receive(:render).with(:nothing => true, :status => :unauthorized)
|
117
|
+
|
118
|
+
@controller.params = {
|
119
|
+
:login => "admin",
|
120
|
+
:password => "password"
|
121
|
+
}
|
122
|
+
@controller.create
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "POST 'destroy'" do
|
129
|
+
before(:each) do
|
130
|
+
@format = mock(:format)
|
131
|
+
@format.stub(:json)
|
132
|
+
@format.stub(:html)
|
133
|
+
@controller.should_receive(:respond_to) do |&block| block.call(@format) end
|
134
|
+
|
135
|
+
@controller.current_session = @session
|
136
|
+
@authentication_service.stub(:sign_out)
|
137
|
+
|
138
|
+
@controller.stub(:sign_in_url) { '/sign-in' }
|
139
|
+
@controller.stub(:reset_session)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should use authentication_service to sign-off" do
|
143
|
+
@authentication_service.should_receive(:sign_out).with(@session)
|
144
|
+
@controller.destroy
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should reset session" do
|
148
|
+
@controller.should_receive(:reset_session)
|
149
|
+
|
150
|
+
@controller.destroy
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "for html" do
|
154
|
+
it "should redirect to sign_in_url" do
|
155
|
+
@format.should_receive(:html) do |&block| block.call end
|
156
|
+
@controller.should_receive(:redirect_to).with("/sign-in")
|
157
|
+
@controller.destroy
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "for json" do
|
162
|
+
it "should render json with sign_in_url" do
|
163
|
+
@format.should_receive(:json) do |&block| block.call end
|
164
|
+
@controller.should_receive(:render).with(:json => {'navigate-to' => '/sign-in'})
|
165
|
+
@controller.destroy
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class AuthenticationSpecController
|
4
|
+
include AuthenticationService::Rails
|
5
|
+
|
6
|
+
# authentication_service { :sign_in_action => '/sign-in',
|
7
|
+
# :sign_out_action => '/sign-out'}
|
8
|
+
|
9
|
+
attr_reader :session
|
10
|
+
attr_accessor :request
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@session = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :respond_to_format
|
17
|
+
def respond_to(&block)
|
18
|
+
yield(@respond_to_format)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe AuthenticationService::Rails do
|
23
|
+
before(:each) do
|
24
|
+
@controller = AuthenticationSpecController.new
|
25
|
+
@controller.request = mock(:request)
|
26
|
+
end
|
27
|
+
|
28
|
+
before(:each) do
|
29
|
+
@authentication_service = mock(:authentication_service)
|
30
|
+
@controller.authentication_service = @authentication_service
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "self.class.authentication_service" do
|
34
|
+
it "should fail if options does not have account" do
|
35
|
+
session_class = mock(:session_class)
|
36
|
+
lambda {
|
37
|
+
AuthenticationSpecController.authentication_service :account => nil, :session => session_class
|
38
|
+
}.should raise_error(RuntimeError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should fail if options does not have session" do
|
42
|
+
account_class = mock(:account_class)
|
43
|
+
lambda {
|
44
|
+
AuthenticationSpecController.authentication_service :account => nil, :account => account_class
|
45
|
+
}.should raise_error(RuntimeError)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should assign account and session classes" do
|
49
|
+
account_class = mock(:account_class)
|
50
|
+
session_class = mock(:session_class)
|
51
|
+
AuthenticationSpecController.authentication_service :account => account_class, :session => session_class
|
52
|
+
AuthenticationSpecController.account_class.should be account_class
|
53
|
+
AuthenticationSpecController.session_class.should be session_class
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "authentication_service=" do
|
58
|
+
it "should return instance with configured account and session classes" do
|
59
|
+
account_class = mock(:account_class)
|
60
|
+
session_class = mock(:session_class)
|
61
|
+
AuthenticationSpecController.authentication_service :account => account_class, :session => session_class
|
62
|
+
@controller.authentication_service = nil
|
63
|
+
@controller.authentication_service.accounts_repository.model_class.should be account_class
|
64
|
+
@controller.authentication_service.sessions_repository.model_class.should be session_class
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "authenticated?" do
|
69
|
+
it "should return true if current sesion is not nil" do
|
70
|
+
@controller.current_session = mock(:session, :blank? => false)
|
71
|
+
@controller.authenticated?.should be_true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return false if current session is nil" do
|
75
|
+
@controller.current_session = mock(:session, :blank? => true)
|
76
|
+
@controller.authenticated?.should be_false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "authenticate" do
|
81
|
+
it "should authenticate_from_session if there is authenticated session id" do
|
82
|
+
@controller.session[:authenticated_session_id] = "some-session-id"
|
83
|
+
@controller.should_receive(:authenticate_from_session) {
|
84
|
+
@controller.current_session = mock(:session, :blank? => false)
|
85
|
+
}
|
86
|
+
@controller.should_not_receive(:redirect_not_authenticated)
|
87
|
+
@controller.authenticate
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should redirect_not_authenticated if not authenticated" do
|
91
|
+
@controller.current_session = mock(:session, :blank? => true)
|
92
|
+
@controller.should_receive(:redirect_not_authenticated)
|
93
|
+
@controller.authenticate
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should not redirect if authenticated" do
|
97
|
+
@controller.current_session = mock(:session, :blank? => false)
|
98
|
+
@controller.should_not_receive(:redirect_not_authenticated)
|
99
|
+
@controller.authenticate
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "authenticate_from_session" do
|
104
|
+
before(:each) do
|
105
|
+
@controller.authentication_service = mock(:authentication_service)
|
106
|
+
@controller.session[:authenticated_session_id] = "authenticated-session-id"
|
107
|
+
@controller.request.stub(:remote_ip).and_return("192.168.48.1")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "uses authentication-service to authenticate by session-id" do
|
111
|
+
@controller.request.should_receive(:remote_ip).and_return("192.168.48.1")
|
112
|
+
@controller.authentication_service.should_receive(:authenticate_by_session_id).with("authenticated-session-id", "192.168.48.1")
|
113
|
+
@controller.send(:authenticate_from_session)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "assigns current_session" do
|
117
|
+
authenticated_session = mock(:authenticated_session)
|
118
|
+
@controller.authentication_service.
|
119
|
+
should_receive(:authenticate_by_session_id).
|
120
|
+
with("authenticated-session-id", "192.168.48.1").
|
121
|
+
and_return(authenticated_session)
|
122
|
+
@controller.send(:authenticate_from_session)
|
123
|
+
@controller.current_session.should be authenticated_session
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "redirect_not_authenticated" do
|
128
|
+
before(:each) do
|
129
|
+
@controller.request.should_receive(:fullpath).and_return('/current-path')
|
130
|
+
@controller.should_receive(:sign_in_url).and_return("/sign-in")
|
131
|
+
@controller.stub(:redirect_to)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should remember current path in session" do
|
135
|
+
@controller.send(:redirect_not_authenticated)
|
136
|
+
@controller.session[:return_to].should eql '/current-path'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should redirect to sign_in_url" do
|
140
|
+
@controller.should_receive(:redirect_to).with("/sign-in")
|
141
|
+
@controller.send(:redirect_not_authenticated)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "redirect_back" do
|
146
|
+
before(:each) do
|
147
|
+
@format = mock(:format)
|
148
|
+
@format.stub(:html)
|
149
|
+
@format.stub(:json)
|
150
|
+
@controller.respond_to_format = @format
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "for html format" do
|
154
|
+
before(:each) do
|
155
|
+
@format.should_receive(:html) do |&block| block.call end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should redirect to previously saved return path" do
|
159
|
+
@controller.session[:return_to] = "/return-path"
|
160
|
+
@controller.should_receive(:redirect_to).with("/return-path")
|
161
|
+
@controller.send(:redirect_back)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should redirect to root_url if no saved return path" do
|
165
|
+
@controller.should_receive(:root_url).and_return("/root-url")
|
166
|
+
@controller.should_receive(:redirect_to).with("/root-url")
|
167
|
+
@controller.send(:redirect_back)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should clear saved return path" do
|
171
|
+
@controller.session[:return_to] = "/return-path"
|
172
|
+
@controller.stub(:redirect_to)
|
173
|
+
@controller.send(:redirect_back)
|
174
|
+
@controller.session[:return_to].should be_nil
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "for json format" do
|
179
|
+
before(:each) do
|
180
|
+
@format.should_receive(:json) do |&block| block.call end
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should render json with previously saved return path" do
|
184
|
+
@controller.session[:return_to] = "/return-path"
|
185
|
+
@controller.should_receive(:render) do |rendered_with|
|
186
|
+
rendered_with[:json]['navigate-to'].should eql '/return-path'
|
187
|
+
end
|
188
|
+
@controller.send(:redirect_back)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should render json with root_url if no saved return path" do
|
192
|
+
@controller.should_receive(:root_url).and_return("/root-url")
|
193
|
+
@controller.should_receive(:render) do |rendered_with|
|
194
|
+
rendered_with[:json]['navigate-to'].should eql '/root-url'
|
195
|
+
end
|
196
|
+
@controller.send(:redirect_back)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should clear saved return path" do
|
200
|
+
@controller.session[:return_to] = "/return-path"
|
201
|
+
@controller.stub(:render)
|
202
|
+
@controller.send(:redirect_back)
|
203
|
+
@controller.session[:return_to].should be_nil
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Session do
|
4
|
+
describe "create_new" do
|
5
|
+
it "should assign account and ip_address" do
|
6
|
+
account = mock(:account)
|
7
|
+
session = Session.create_new(account, "localhost")
|
8
|
+
session.account.should be account
|
9
|
+
session.ip_address.should eql "localhost"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should generate new random session_id" do
|
13
|
+
session1 = Session.create_new(mock(:account), "localhost")
|
14
|
+
session2 = Session.create_new(mock(:account), "localhost")
|
15
|
+
|
16
|
+
session1.session_id.should_not be_nil
|
17
|
+
session2.session_id.should_not be_nil
|
18
|
+
|
19
|
+
session1.session_id.should_not eql session2.session_id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
# Set up gems listed in the Gemfile.
|
4
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
5
|
+
|
6
|
+
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
7
|
+
|
8
|
+
require 'rspec'
|
9
|
+
require 'authentication-service'
|
10
|
+
|
11
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
12
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
13
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
14
|
+
# loaded once.
|
15
|
+
#
|
16
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
|
+
RSpec.configure do |config|
|
18
|
+
include AuthenticationService
|
19
|
+
|
20
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
21
|
+
config.run_all_when_everything_filtered = true
|
22
|
+
config.filter_run :focus
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: authentication-service
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.a1
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Evgeny Myasishchev
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70191597925800 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70191597925800
|
25
|
+
description: Provides authentication related stuff.
|
26
|
+
email:
|
27
|
+
- evgeny.myasishchev@gmail.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- .rspec
|
34
|
+
- .rvmrc
|
35
|
+
- Gemfile
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- authentication-service.gemspec
|
39
|
+
- lib/authentication-service.rb
|
40
|
+
- lib/authentication-service/account.rb
|
41
|
+
- lib/authentication-service/base.rb
|
42
|
+
- lib/authentication-service/persistance.rb
|
43
|
+
- lib/authentication-service/persistance/accounts-repository.rb
|
44
|
+
- lib/authentication-service/persistance/sessions-repository.rb
|
45
|
+
- lib/authentication-service/rails.rb
|
46
|
+
- lib/authentication-service/rails/sessions-controller-actions.rb
|
47
|
+
- lib/authentication-service/session.rb
|
48
|
+
- lib/authentication-service/version.rb
|
49
|
+
- spec/lib/account_spec.rb
|
50
|
+
- spec/lib/base_spec.rb
|
51
|
+
- spec/lib/persistance/accounts_repository_spec.rb
|
52
|
+
- spec/lib/persistance/sessions_repository_spec.rb
|
53
|
+
- spec/lib/persistance_spec.rb
|
54
|
+
- spec/lib/rails_sessions_controller_actions_spec.rb
|
55
|
+
- spec/lib/rails_spec.rb
|
56
|
+
- spec/lib/session_spec.rb
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
homepage: ''
|
59
|
+
licenses: []
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>'
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.1
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project: authentication-service
|
78
|
+
rubygems_version: 1.8.15
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: Authentication service for Rails (and not only)
|
82
|
+
test_files:
|
83
|
+
- spec/lib/account_spec.rb
|
84
|
+
- spec/lib/base_spec.rb
|
85
|
+
- spec/lib/persistance/accounts_repository_spec.rb
|
86
|
+
- spec/lib/persistance/sessions_repository_spec.rb
|
87
|
+
- spec/lib/persistance_spec.rb
|
88
|
+
- spec/lib/rails_sessions_controller_actions_spec.rb
|
89
|
+
- spec/lib/rails_spec.rb
|
90
|
+
- spec/lib/session_spec.rb
|
91
|
+
- spec/spec_helper.rb
|