currentuser-services 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 94878212c7bc434fdee19a6e540ccf1c4eaf9fd1
4
+ data.tar.gz: 4f4b78e39e7c871cc1e9c82f63026fa96c6dc49e
5
+ SHA512:
6
+ metadata.gz: 5ac7cc36b8bb1e21fd296bda9a945927a70c1455bef48676ee20b89e0e266a7de73a21480e00f75df8dad88cbe0be002b64d8ff2109c26abd4af33a16da14640
7
+ data.tar.gz: 8c0220347aa8d37fbb551ccd780f1ee64ae0e76ef6f831aac0ca365614eeb712f0b964c2282be88896d09f556ceea8431539bd36ae312beeb33a25bac3595b5b
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Add dependencies required to use your gem here.
4
+ gem 'gem_config'
5
+ gem 'encrypto_signo'
6
+ gem 'rails', '~>4.0'
7
+
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem 'awesome_print'
12
+ gem 'minitest-reporters'
13
+ gem 'dotenv'
14
+ gem 'bundler', '~> 1.0'
15
+ gem 'jeweler', '~> 2.0.1'
16
+ gem 'minitest-rails-capybara'
17
+ gem 'capybara-mechanize'
18
+ gem 'currentuser-data', path: '~/dev/currentuser-data-gem'
19
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 eric-currentuser
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # currentuser-services
2
+
3
+ Offsite sign up and sign in forms for [Currentuser.io](http://www.currentuser.io).
4
+
5
+ If you want to manage your own sign_up, sign_in and sign_out actions you should use the gem `currentuser-data` instead.
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/currentuser-services.svg)](http://badge.fury.io/rb/currentuser-services)
8
+
9
+ ## Configuration
10
+
11
+ Create your project on [Currentuser.io](http://www.currentuser.io).
12
+
13
+ Add `currentuser-services` gem in your `Gemfile`:
14
+ ```ruby
15
+ # Gemfile
16
+ gem 'currentuser-services'
17
+ ```
18
+ Add an initializer file:
19
+ ```ruby
20
+ # config/initializers/currentuser.rb (the exact name of the file has no impact)
21
+ Currentuser::Services.configure do |config|
22
+ config.project_id = 'your_project_id'
23
+ end
24
+ ```
25
+ Call `currentuser` in your routes definition:
26
+ ```ruby
27
+ # config/routes.rb
28
+ MyApplication::Application.routes.draw do
29
+ currentuser
30
+ end
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ * Use `currentuser_sign_up_url`, `currentuser_sign_in_url` and `currentuser_sign_out_url`in your navigation to allow
36
+ visitor to sign up, in and out
37
+ * Use `:require_currentuser` as `before_action` to protect your restricted actions
38
+ * In any action or view, you can use `currentuser_id` to retrieve the id of the connected user (if any)
39
+
40
+ That's all! Note that:
41
+
42
+ * you don't need to generate and run migrations. Currentuser does NOT rely on your database
43
+ * you don't need to generate, analyse and modify a complicated configuration file.
44
+
45
+ ### Example
46
+
47
+ #### Routes
48
+
49
+ ```ruby
50
+ # config/routes.rb
51
+ MyApplication::Application.routes.draw do
52
+ root 'main#index'
53
+ get :restricted, to: 'main#restricted'
54
+ currentuser
55
+ end
56
+ ```
57
+
58
+ #### Controller
59
+
60
+ ```ruby
61
+ class MainController < ApplicationController
62
+ before_action :require_currentuser, only: :restricted
63
+ end
64
+ ```
65
+
66
+ #### Views
67
+
68
+ ```haml
69
+ -# views/home/index.html.haml
70
+ = render 'shared/menu'
71
+
72
+ %h1
73
+ Welcome!
74
+ ```
75
+
76
+ ```haml
77
+ -# views/home/restricted.html.haml
78
+ = render 'shared/menu'
79
+
80
+ %h1
81
+ Welcome back to this restricted area, #{currentuser_id}
82
+ ```
83
+
84
+ ```haml
85
+ -# views/shared/_menu.html.haml
86
+ %ul
87
+ - if currentuser_id
88
+ %li
89
+ = link_to 'Home', :root
90
+ %li
91
+ = link_to 'Restricted', :restricted
92
+ %li
93
+ = link_to 'Sign out', currentuser_sign_out_url
94
+ - else
95
+ %li
96
+ = link_to 'Sign up', currentuser_sign_up_url
97
+ %li
98
+ = link_to 'Sign in', currentuser_sign_in_url
99
+ ```
100
+
101
+ ## Contributing to currentuser-services (not recommended yet)
102
+
103
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
104
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
105
+ * Fork the project.
106
+ * Start a feature/bugfix branch.
107
+ * Commit and push until you are happy with your contribution.
108
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
109
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
110
+
111
+ ### Tests
112
+
113
+ TBD
114
+
115
+ ## Copyright
116
+
117
+ Copyright (c) 2014 eric-currentuser. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts 'Run `bundle install` to install missing gems'
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = 'currentuser-services'
18
+ gem.homepage = 'http://github.com/currentuser/currentuser-services-gem'
19
+ gem.license = 'MIT'
20
+ gem.summary = %Q{Offsite sign up and sign in forms for Currentuser.io}
21
+ gem.description = %Q{Offsite sign up and sign in forms for Currentuser.io}
22
+ gem.email = 'TBD'
23
+ gem.authors = ["eric-currentuser"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,26 @@
1
+ module Currentuser
2
+ module Services
3
+ class SessionsController < ActionController::Base
4
+
5
+ def sign_in
6
+ Services.check_authentication_params!(params)
7
+
8
+ # Log in
9
+ session[:currentuser_id] = params[:currentuser_id]
10
+
11
+ redirect_to '/'
12
+ end
13
+
14
+ def sign_out
15
+ session.delete(:currentuser_id)
16
+
17
+ redirect_to '/'
18
+ end
19
+
20
+ def available
21
+ head :ok
22
+ end
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,9 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7XrSJNBNHd+KgBCmMaKm
3
+ cuN046QvNrtIRGtCglKmEzMUbjOeNGcC3jJsL1FVpmHD8+/FcOBwDN1DPagRYFL2
4
+ jVMVs2bhCD0SyhWoStvPNSDJRIOxxKHdwvGlQ2vNRnA+SEmpSx7dGmXy5Zhe9z6P
5
+ G7Nbtc3uxCJGzZmBQL3M+Qsi71RvmX9DmARCezOMI+iKkvo9XW8cTaRrAwsEySSX
6
+ OmzcSOvkbThX3R6UY8exIZ/sqmPv5nnhdz91IkcIEP9UzId39ECavt7cYmNs9hz+
7
+ oIaLRNosB2w5+5JH7r2UcEVnydjFeD/w+3ZH8+d47XBGgyR9jHB6c+EmjIEL5xp0
8
+ swIDAQAB
9
+ -----END PUBLIC KEY-----
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Currentuser::Services::Engine.routes.draw do
2
+ root 'sessions#available'
3
+ get :sign_in, to: 'sessions#sign_in'
4
+ get :sign_out, to: 'sessions#sign_out'
5
+ end
@@ -0,0 +1,88 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: currentuser-services 0.0.1 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "currentuser-services"
9
+ s.version = "0.0.1"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["eric-currentuser"]
14
+ s.date = "2014-12-15"
15
+ s.description = "Offsite sign up and sign in forms for Currentuser.io"
16
+ s.email = "TBD"
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ "Gemfile",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "app/controllers/currentuser/services/sessions_controller.rb",
29
+ "config/currentuser-services_public_key.txt",
30
+ "config/routes.rb",
31
+ "currentuser-services.gemspec",
32
+ "lib/currentuser/services.rb",
33
+ "lib/currentuser/services/controllers/authenticates.rb",
34
+ "lib/currentuser/services/engine.rb",
35
+ "test/currentuser/services/authenticates_test.rb",
36
+ "test/currentuser/services/integration_test.rb",
37
+ "test/currentuser/services_test.rb",
38
+ "test/helper.rb",
39
+ "test/test_application/application.rb"
40
+ ]
41
+ s.homepage = "http://github.com/currentuser/currentuser-services-gem"
42
+ s.licenses = ["MIT"]
43
+ s.rubygems_version = "2.2.2"
44
+ s.summary = "Offsite sign up and sign in forms for Currentuser.io"
45
+
46
+ if s.respond_to? :specification_version then
47
+ s.specification_version = 4
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_runtime_dependency(%q<gem_config>, [">= 0"])
51
+ s.add_runtime_dependency(%q<encrypto_signo>, [">= 0"])
52
+ s.add_runtime_dependency(%q<rails>, ["~> 4.0"])
53
+ s.add_development_dependency(%q<awesome_print>, [">= 0"])
54
+ s.add_development_dependency(%q<minitest-reporters>, [">= 0"])
55
+ s.add_development_dependency(%q<dotenv>, [">= 0"])
56
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
57
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
58
+ s.add_development_dependency(%q<minitest-rails-capybara>, [">= 0"])
59
+ s.add_development_dependency(%q<capybara-mechanize>, [">= 0"])
60
+ s.add_development_dependency(%q<currentuser-data>, [">= 0"])
61
+ else
62
+ s.add_dependency(%q<gem_config>, [">= 0"])
63
+ s.add_dependency(%q<encrypto_signo>, [">= 0"])
64
+ s.add_dependency(%q<rails>, ["~> 4.0"])
65
+ s.add_dependency(%q<awesome_print>, [">= 0"])
66
+ s.add_dependency(%q<minitest-reporters>, [">= 0"])
67
+ s.add_dependency(%q<dotenv>, [">= 0"])
68
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
69
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
70
+ s.add_dependency(%q<minitest-rails-capybara>, [">= 0"])
71
+ s.add_dependency(%q<capybara-mechanize>, [">= 0"])
72
+ s.add_dependency(%q<currentuser-data>, [">= 0"])
73
+ end
74
+ else
75
+ s.add_dependency(%q<gem_config>, [">= 0"])
76
+ s.add_dependency(%q<encrypto_signo>, [">= 0"])
77
+ s.add_dependency(%q<rails>, ["~> 4.0"])
78
+ s.add_dependency(%q<awesome_print>, [">= 0"])
79
+ s.add_dependency(%q<minitest-reporters>, [">= 0"])
80
+ s.add_dependency(%q<dotenv>, [">= 0"])
81
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
82
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
83
+ s.add_dependency(%q<minitest-rails-capybara>, [">= 0"])
84
+ s.add_dependency(%q<capybara-mechanize>, [">= 0"])
85
+ s.add_dependency(%q<currentuser-data>, [">= 0"])
86
+ end
87
+ end
88
+
@@ -0,0 +1,45 @@
1
+ require 'gem_config'
2
+ require 'encrypto_signo'
3
+ require 'rails'
4
+ require 'currentuser/services/controllers/authenticates'
5
+ require 'currentuser/services/engine'
6
+
7
+ module Currentuser
8
+ module Services
9
+ include GemConfig::Base
10
+
11
+ with_configuration do
12
+ # Public API
13
+ has :project_id, classes: String
14
+
15
+ # Developer API
16
+ has :currentuser_services_host, classes: String
17
+ has :currentuser_services_public_key, classes: String
18
+ has :currentuser_project_id_for_tests, classes: String
19
+ end
20
+ end
21
+ end
22
+
23
+ Currentuser::Services.configure do |config|
24
+ config.currentuser_services_host = 'http://services.currentuser.io'
25
+ config.currentuser_services_public_key = File.read(
26
+ File.join(File.dirname(__FILE__), '..', '..', 'config', 'currentuser-services_public_key.txt')
27
+ )
28
+ end
29
+
30
+ module ActionController
31
+ class Base
32
+ include Currentuser::Services::Authenticates
33
+ helper_method :currentuser_id, :currentuser_sign_in_url, :currentuser_sign_up_url, :currentuser_sign_out_url
34
+ end
35
+ end
36
+
37
+ class ActionDispatch::Routing::Mapper
38
+ def currentuser
39
+ mount Currentuser::Services::Engine => '/currentuser'
40
+ end
41
+ end
42
+
43
+ # For an unclear reason, we have to require this file late in the process, otherwise using application have
44
+ # problems on start up
45
+ require 'controllers/currentuser/services/sessions_controller'
@@ -0,0 +1,65 @@
1
+ module Currentuser
2
+ module Services
3
+ module Authenticates
4
+ def require_currentuser
5
+ return if currentuser_id
6
+ redirect_to currentuser_sign_in_url
7
+ end
8
+
9
+ def currentuser_id
10
+ return @currentuser_id ||= session[:currentuser_id]
11
+ end
12
+
13
+ def currentuser_sign_in_url
14
+ return Services.currentuser_url(:sign_in)
15
+ end
16
+
17
+ def currentuser_sign_up_url
18
+ return Services.currentuser_url(:sign_up)
19
+ end
20
+
21
+ def currentuser_sign_out_url
22
+ return currentuser_services.sign_out_url
23
+ end
24
+ end
25
+
26
+ def self.check_authentication_params!(params)
27
+ raise unless params[:currentuser_id] && params[:timestamp] && params[:signature]
28
+
29
+ # Check timestamp
30
+ unless timestamp_recent?(params[:timestamp].to_i)
31
+ raise TimestampTooOld, 'Timestamp is more than 10 minutes old'
32
+ end
33
+
34
+ # Check signature
35
+ auth_string = [params[:currentuser_id], params[:timestamp]].join
36
+ unless signature_authentic?(params[:signature], auth_string)
37
+ raise SignatureNotAuthentic, 'Signature verification failed'
38
+ end
39
+ end
40
+
41
+ def self.currentuser_url(action)
42
+ return currentuser_url_for_project_id(configuration.project_id, action)
43
+ end
44
+
45
+ def self.currentuser_url_for_project_id(project_id, action)
46
+ host = configuration.currentuser_services_host
47
+ raise 'project_id should be set' unless project_id
48
+ raise 'action should be :sign_up or :sign_in' unless action.in?([:sign_up, :sign_in])
49
+ return "#{host}/#{project_id}/#{action}"
50
+ end
51
+
52
+ Error = Class.new(StandardError)
53
+ TimestampTooOld = Class.new(Error)
54
+ SignatureNotAuthentic = Class.new(Error)
55
+
56
+ def self.timestamp_recent?(timestamp)
57
+ return (Time.now - Time.at(timestamp)).abs < 10 * 60
58
+ end
59
+
60
+ def self.signature_authentic?(signature, auth_string)
61
+ public_key = Services.configuration.currentuser_services_public_key
62
+ return EncryptoSigno.verify(public_key, signature, auth_string)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,5 @@
1
+ module Currentuser::Services
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Currentuser::Services
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ require 'helper'
2
+
3
+ module Currentuser
4
+ module Services
5
+
6
+ class TestAuthenticatesController < ActionController::Base
7
+ before_action :require_currentuser
8
+
9
+ def test_action_requiring_user
10
+ head :ok
11
+ end
12
+ end
13
+
14
+ class AuthenticatesTest < ActionController::TestCase
15
+ tests TestAuthenticatesController
16
+
17
+ def get_with_route(action)
18
+ with_routing do |map|
19
+ map.draw do
20
+ namespace :currentuser do
21
+ namespace :services do
22
+ get '/any_path', to: 'test_authenticates#test_action_requiring_user'
23
+ end
24
+ end
25
+ end
26
+ get action
27
+ end
28
+ end
29
+
30
+ # require_currentuser
31
+
32
+ test 'execute action if currentuser_id is available' do
33
+ session[:currentuser_id] = 'user_id_1'
34
+
35
+ get_with_route :test_action_requiring_user
36
+ assert_response :ok
37
+ end
38
+
39
+ test 'redirects to sign_in URL if currentuser_id is not available' do
40
+ assert_nil session[:currentuser_id]
41
+
42
+ get_with_route :test_action_requiring_user
43
+ assert_response :redirect
44
+ assert_redirected_to Services.currentuser_url(:sign_in)
45
+ end
46
+
47
+ # currentuser_id
48
+
49
+ test 'currentuser_id returns currentuser ID' do
50
+ session[:currentuser_id] = 'user_id_1'
51
+
52
+ assert_equal 'user_id_1', @controller.currentuser_id
53
+ end
54
+
55
+ # sign_in_url
56
+
57
+ test 'sign_in_url returns the expected url' do
58
+ assert_equal "http://localhost:3001/#{Services.configuration.project_id}/sign_in", @controller.currentuser_sign_in_url
59
+ end
60
+
61
+ # sign_up_url
62
+
63
+ test 'sign_up_url returns the expected url' do
64
+ assert_equal "http://localhost:3001/#{Services.configuration.project_id}/sign_up", @controller.currentuser_sign_up_url
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,82 @@
1
+ require 'helper'
2
+
3
+ # Apparently we need to require the routes. Not sure why.
4
+ require_relative '../../../config/routes'
5
+
6
+ # Load test application
7
+ require 'rails/generators' # Not sure why we need that
8
+ require 'test_application/application'
9
+
10
+ require 'minitest/rails/capybara'
11
+ require 'capybara/mechanize'
12
+
13
+ require 'currentuser/data'
14
+ require 'currentuser/data/test/helpers'
15
+
16
+ #Rails.logger = Logger.new(STDOUT)
17
+ Rails.logger = Logger.new('/dev/null')
18
+
19
+ Currentuser::Data::BaseResource.site = ENV['CURRENTUSER_DATA_URL']
20
+ Currentuser::Data::Test::UseReadApi.currentuser_project_id_for_tests =
21
+ Currentuser::Services.configuration.project_id
22
+
23
+ module Currentuser
24
+ module Services
25
+ Capybara.current_driver = :mechanize
26
+ class IntegrationTest < ActionDispatch::IntegrationTest
27
+ include Capybara::DSL
28
+ include Currentuser::Data::Test::UseWriteApi
29
+
30
+ teardown do
31
+ Capybara.reset_sessions! # Forget the (simulated) browser state
32
+ end
33
+
34
+ test 'one can visit public page' do
35
+
36
+ visit '/'
37
+ assert_equal '/', current_path
38
+ assert has_text? 'Public page'
39
+ end
40
+
41
+ test 'sign in and sign out' do
42
+ Currentuser::Data::User.create(email: 'email@example.org', password: 'password')
43
+ visit '/inside'
44
+ assert_match /sign_in/, current_path
45
+
46
+ fill_in 'Email', with: 'email@example.org'
47
+ fill_in 'Password', with: 'password'
48
+ click_button 'Sign In'
49
+
50
+ visit '/inside'
51
+ assert_equal '/inside', current_path
52
+ assert has_text? 'Private page'
53
+
54
+ visit 'currentuser/sign_out'
55
+ assert_equal '/', current_path
56
+
57
+ visit '/inside'
58
+ assert_match /sign_in/, current_path
59
+ end
60
+
61
+ test 'sign up' do
62
+ visit Services.currentuser_url(:sign_up)
63
+
64
+ fill_in 'Email', with: 'email@example.org'
65
+ fill_in 'Password', with: 'password'
66
+ click_button 'Sign Up'
67
+ assert_equal '/', current_path
68
+ assert has_text? 'Public page'
69
+
70
+ # Check user is connected
71
+ visit '/inside'
72
+ assert has_text? 'Private page'
73
+ end
74
+
75
+ test 'available' do
76
+ visit '/currentuser'
77
+
78
+ assert_equal 200, page.status_code
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,83 @@
1
+ require 'helper'
2
+
3
+ module Currentuser
4
+ module Services
5
+
6
+ class ServicesTest < ActiveSupport::TestCase
7
+
8
+ # timestamp_recent?
9
+
10
+ test 'timestamp_recent? returns the expected result' do
11
+ assert Services.timestamp_recent?(Time.now)
12
+ assert Services.timestamp_recent?(Time.now - 9 * 60)
13
+ assert Services.timestamp_recent?(Time.now + 9 * 60)
14
+ refute Services.timestamp_recent?(Time.now - 11 * 60)
15
+ refute Services.timestamp_recent?(Time.now + 11 * 60)
16
+ end
17
+
18
+ # signature_authentic?
19
+
20
+ test 'signature_authentic returns the expected result' do
21
+ timestamp = 100000
22
+ user_id = 'user_id_1'
23
+ signature = "RmYbwPNZc418905uSHHmrmkKcekj7OQw8zU372g6aEuMufOExuEJcSH3Zokq\nbJLFT89wxcF0/s9Ks2EV3cmuvoe5RQeanro7a0m+KpZskBt3IqxRiXFGr6sE\nvBfWrDQC24lJjKjIn76qMvwd/A6PmN0uyQz/QtE1FjXdNauYPq9xJoSPdL+T\nr3Y8uCnBkT8E1AwuiMC9zIjQVEBukmbR9LW8QNvg3+vdJfoxIsf4Gxxs5V6e\n0r7fk5Vz5uws3D/DmUWnfRaPaW9KYVB5VoOAD/P2TlGNZ7wurlYXuHPfK0QX\njkThXYrpFn6m5u2rVyFoNanroDTqIcndKxLDeXE0sg==\n"
24
+
25
+ assert Services.signature_authentic?(signature, "#{user_id}#{timestamp}")
26
+ refute Services.signature_authentic?(signature, "0#{user_id}#{timestamp}")
27
+ refute Services.signature_authentic?("0#{signature}", "#{user_id}#{timestamp}")
28
+ end
29
+
30
+ # check_authentication_params!
31
+
32
+ test 'can authenticate (stubbing :timestamp_recent?)' do
33
+
34
+ # These data have been prepare using current-services private key.
35
+ timestamp = 100000
36
+ user_id = 'user_id_1'
37
+ signature = "RmYbwPNZc418905uSHHmrmkKcekj7OQw8zU372g6aEuMufOExuEJcSH3Zokq\nbJLFT89wxcF0/s9Ks2EV3cmuvoe5RQeanro7a0m+KpZskBt3IqxRiXFGr6sE\nvBfWrDQC24lJjKjIn76qMvwd/A6PmN0uyQz/QtE1FjXdNauYPq9xJoSPdL+T\nr3Y8uCnBkT8E1AwuiMC9zIjQVEBukmbR9LW8QNvg3+vdJfoxIsf4Gxxs5V6e\n0r7fk5Vz5uws3D/DmUWnfRaPaW9KYVB5VoOAD/P2TlGNZ7wurlYXuHPfK0QX\njkThXYrpFn6m5u2rVyFoNanroDTqIcndKxLDeXE0sg==\n"
38
+
39
+ # As we use a fixed timestamp we have to simulate it is recent
40
+ Services.stub :timestamp_recent?, true do
41
+ Services.check_authentication_params! currentuser_id: user_id, timestamp: timestamp, signature: signature
42
+ end
43
+ end
44
+
45
+ test 'can authenticate (stubbing :signature_authentic?)' do
46
+
47
+ # Take a recent timestamp
48
+ timestamp = (Time.now - 60).to_i.to_s
49
+ user_id = 'user_id_1'
50
+ signature = 'any_signature'
51
+
52
+ # By pass signature checking
53
+ Services.stub :signature_authentic?, true do
54
+ Services.check_authentication_params! currentuser_id: user_id, timestamp: timestamp, signature: signature
55
+ end
56
+ end
57
+
58
+ test 'raises if timestamp too old' do
59
+
60
+ # Take an old timestamp (and an invalid signature, but this has no impact)
61
+ timestamp = (Time.now - 15 * 60).to_i.to_s
62
+ user_id = 'user_id_1'
63
+ signature = 'any_signature'
64
+
65
+ assert_raises Services::TimestampTooOld do
66
+ Services.check_authentication_params! currentuser_id: user_id, timestamp: timestamp, signature: signature
67
+ end
68
+ end
69
+
70
+ test 'raises if signature invalid' do
71
+
72
+ # Take a recent timestamp and an invalid signature
73
+ timestamp = (Time.now - 60).to_i.to_s
74
+ user_id = 'user_id_1'
75
+ signature = 'any_signature'
76
+
77
+ assert_raises Services::SignatureNotAuthentic do
78
+ Services.check_authentication_params! currentuser_id: user_id, timestamp: timestamp, signature: signature
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup(:default, :development)
4
+
5
+ require 'minitest/autorun'
6
+ require 'minitest/reporters'
7
+ Minitest::Reporters.use!
8
+
9
+ require 'awesome_print'
10
+ require 'action_controller'
11
+ require 'dotenv'
12
+ Dotenv.load
13
+
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'app'))
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+ require 'currentuser/services'
18
+
19
+ Currentuser::Services.configure do |config|
20
+ config.project_id = ENV['CURRENTUSER_PROJECT_ID_FOR_TESTS']
21
+ end
22
+
23
+ Currentuser::Services.configure do |config|
24
+ config.currentuser_services_host = ENV['CURRENTUSER_SERVICES_HOST']
25
+ config.currentuser_services_public_key = ENV['CURRENTUSER_SERVICES_PUBLIC_KEY']
26
+ end
@@ -0,0 +1,23 @@
1
+ module TestRailsApp
2
+ class Application < Rails::Application
3
+ config.secret_token = 'f6da1f7d3105c589bc3f36f3e78ee794'
4
+
5
+ routes.draw do
6
+ root 'test_rails_app/homes#outside'
7
+ currentuser
8
+ get '/inside' => 'test_rails_app/homes#inside'
9
+ end
10
+ end
11
+
12
+ class HomesController < ActionController::Base
13
+ before_action :require_currentuser, except: :outside
14
+
15
+ def outside
16
+ render text: 'Public page'
17
+ end
18
+
19
+ def inside
20
+ render text: 'Private page'
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,217 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: currentuser-services
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - eric-currentuser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gem_config
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: encrypto_signo
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: awesome_print
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-reporters
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dotenv
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: jeweler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.0.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 2.0.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: minitest-rails-capybara
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: capybara-mechanize
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: currentuser-data
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '>='
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: Offsite sign up and sign in forms for Currentuser.io
168
+ email: TBD
169
+ executables: []
170
+ extensions: []
171
+ extra_rdoc_files:
172
+ - LICENSE.txt
173
+ - README.md
174
+ files:
175
+ - .document
176
+ - Gemfile
177
+ - LICENSE.txt
178
+ - README.md
179
+ - Rakefile
180
+ - VERSION
181
+ - app/controllers/currentuser/services/sessions_controller.rb
182
+ - config/currentuser-services_public_key.txt
183
+ - config/routes.rb
184
+ - currentuser-services.gemspec
185
+ - lib/currentuser/services.rb
186
+ - lib/currentuser/services/controllers/authenticates.rb
187
+ - lib/currentuser/services/engine.rb
188
+ - test/currentuser/services/authenticates_test.rb
189
+ - test/currentuser/services/integration_test.rb
190
+ - test/currentuser/services_test.rb
191
+ - test/helper.rb
192
+ - test/test_application/application.rb
193
+ homepage: http://github.com/currentuser/currentuser-services-gem
194
+ licenses:
195
+ - MIT
196
+ metadata: {}
197
+ post_install_message:
198
+ rdoc_options: []
199
+ require_paths:
200
+ - lib
201
+ required_ruby_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - '>='
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ required_rubygems_version: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - '>='
209
+ - !ruby/object:Gem::Version
210
+ version: '0'
211
+ requirements: []
212
+ rubyforge_project:
213
+ rubygems_version: 2.2.2
214
+ signing_key:
215
+ specification_version: 4
216
+ summary: Offsite sign up and sign in forms for Currentuser.io
217
+ test_files: []