currentuser-services 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +20 -0
- data/README.md +117 -0
- data/Rakefile +35 -0
- data/VERSION +1 -0
- data/app/controllers/currentuser/services/sessions_controller.rb +26 -0
- data/config/currentuser-services_public_key.txt +9 -0
- data/config/routes.rb +5 -0
- data/currentuser-services.gemspec +88 -0
- data/lib/currentuser/services.rb +45 -0
- data/lib/currentuser/services/controllers/authenticates.rb +65 -0
- data/lib/currentuser/services/engine.rb +5 -0
- data/test/currentuser/services/authenticates_test.rb +68 -0
- data/test/currentuser/services/integration_test.rb +82 -0
- data/test/currentuser/services_test.rb +83 -0
- data/test/helper.rb +26 -0
- data/test/test_application/application.rb +23 -0
- metadata +217 -0
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
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,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,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: []
|