facemock-oauth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ tmp/
19
+ vendor/bundle/
20
+ vendor/bundler/
21
+ log/*.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in facemock-oauth.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 ogawa
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ [![Gem Version](https://badge.fury.io/rb/facemock-oauth.svg)](http://badge.fury.io/rb/facemock-oauth)
2
+ [![Build Status](https://travis-ci.org/ogawatti/facemock-oauth.svg?branch=master)](https://travis-ci.org/ogawatti/facemock-oauth)
3
+ [![Coverage Status](https://coveralls.io/repos/ogawatti/facemock-oauth/badge.png?branch=master)](https://coveralls.io/r/ogawatti/facemock-oauth?branch=master)
4
+ [<img src="https://gemnasium.com/ogawatti/facemock-oauth.png" />](https://gemnasium.com/ogawatti/facemock-oauth)
5
+ [![Code Climate](https://codeclimate.com/github/ogawatti/facemock-oauth/badges/gpa.svg)](https://codeclimate.com/github/ogawatti/facemock-oauth)
6
+
7
+ # Facemock::Oauth
8
+
9
+ Facemock::OAuth will mock the oauth of facebook using facemock.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'facemock-oauth'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install facemock-oauth
24
+
25
+ ## Usage
26
+
27
+ ### Facemock OAuth
28
+
29
+ for Rails
30
+
31
+ $ vi config/routes.rb
32
+
33
+ YourApp::Application.routes.draw do
34
+ devise_scope :user do
35
+ match ':provider/sign_in', to: 'your_sign_in_controller'
36
+ match 'users/facemock/auth/callback', to: 'your_callback_controller'
37
+ end
38
+ end
39
+
40
+ $ vi config/environments/development.rb
41
+
42
+ Facemock::OAuth::LoginHook.path = '/facebook/sign_in'
43
+ Facemock::OAuth::CallbackHook.path = '/users/facemock/auth/callback'
44
+
45
+ config.middleware.use Facemock::OAuth::LoginHook
46
+ config.middleware.use Facemock::OAuth::Login
47
+ config.middleware.use Facemock::OAuth::Authentication
48
+ config.middleware.use Facemock::OAuth::CallbackHook
49
+
50
+ for Sinatra
51
+
52
+ $ vi config.ru
53
+
54
+ require 'sinatra'
55
+ require 'facemock-oauth'
56
+
57
+ Facemock::OAuth::LoginHook.path = '/facebook/sign_in'
58
+ Facemock::OAuth::CallbackHook.path = '/users/facemock/auth/callback'
59
+
60
+ use Facemock::OAuth::LoginHook
61
+ use Facemock::OAuth::Login
62
+ use Facemock::OAuth::Authentication
63
+ use Facemock::OAuth::CallbackHook
64
+
65
+ require File.expand_path 'app', File.dirname(__FILE__)
66
+
67
+ run Sinatra::Application
68
+
69
+ ### User registration to Facemock
70
+
71
+ See the [https://github.com/ogawatti/facemock](facemock).
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'facemock/oauth/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "facemock-oauth"
8
+ spec.version = Facemock::OAuth::VERSION
9
+ spec.authors = ["ogawatti"]
10
+ spec.email = ["ogawattim@gmail.com"]
11
+ spec.description = %q{This gem will mock the oauth of facebook using facemock.}
12
+ spec.summary = %q{This is facebook oauth mock application.}
13
+ spec.homepage = "https://github.com/ogawatti/facemock-oauth"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "facemock"
22
+ spec.add_dependency "rack"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "rack-test"
28
+ spec.add_development_dependency "simplecov"
29
+ spec.add_development_dependency "coveralls"
30
+ spec.add_development_dependency "pry"
31
+ end
@@ -0,0 +1,11 @@
1
+ require "facemock/oauth/version"
2
+ require "facemock/oauth/rack_middleware"
3
+ require "facemock/oauth/login"
4
+ require "facemock/oauth/login_hook"
5
+ require "facemock/oauth/authentication"
6
+ require "facemock/oauth/callback_hook"
7
+
8
+ module Facemock
9
+ module OAuth
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ require 'facemock'
2
+
3
+ module Facemock
4
+ module OAuth
5
+ class Authentication < RackMiddleware
6
+ DEFAULT_PATH = "/facemock/oauth"
7
+ @path = DEFAULT_PATH
8
+
9
+ def call(env)
10
+ if env["PATH_INFO"] == Authentication.path && env["REQUEST_METHOD"] == "POST"
11
+ raw_body = env['rack.input'].gets
12
+ body = query_string_to_hash(raw_body)
13
+ email = body["email"]
14
+ password = body["pass"]
15
+
16
+ user = Facemock::Database::User.find_by_email(email)
17
+ if user && user.password == password
18
+ code = Facemock::Database::AuthorizationCode.create!(user_id: user.id)
19
+ location = location(env, CallbackHook.path, { code: code.string })
20
+ else
21
+ location = location(env, "/facemock/sign_in")
22
+ end
23
+
24
+ code = 302
25
+ body = []
26
+ header = { "Content-Type" => "text/html;charset=utf-8",
27
+ "Location" => location,
28
+ "Content-Length" => content_length(body).to_s,
29
+ "X-XSS-Protection" => "1; mode=block",
30
+ "X-Content-Type-Options" => "nosniff",
31
+ "X-Frame-Options" => "SAMEORIGIN" }
32
+ [ code, header, body ]
33
+ else
34
+ super
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,32 @@
1
+ require 'facemock'
2
+
3
+ module Facemock
4
+ module OAuth
5
+ class CallbackHook < RackMiddleware
6
+ DEFAULT_PATH = "/users/auth/callback"
7
+ @path = DEFAULT_PATH
8
+
9
+ def call(env)
10
+ if env["PATH_INFO"] == CallbackHook.path
11
+ query = query_string_to_hash(env["QUERY_STRING"])
12
+ if access_token = get_access_token(query["code"])
13
+ env["omniauth.auth"] = Facemock.auth_hash(access_token)
14
+ end
15
+ end
16
+ super(env)
17
+ end
18
+
19
+ private
20
+
21
+ def get_access_token(code)
22
+ authorization_code = Facemock::Database::AuthorizationCode.find_by_string(code)
23
+ if authorization_code
24
+ user = Facemock::Database::User.find_by_id(authorization_code.user_id)
25
+ user ? user.access_token : nil
26
+ else
27
+ nil
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Facemock
4
+ module OAuth
5
+ class Login < RackMiddleware
6
+ VIEW_DIRECTORY = File.expand_path("../../../../view", __FILE__)
7
+ VIEW_FILE_NAME = "login.html"
8
+ DEFAULT_PATH = "/facemock/sign_in"
9
+ @path = DEFAULT_PATH
10
+
11
+ def call(env)
12
+ if env["PATH_INFO"] == Login.path
13
+ code = 200
14
+ body = [ Login.view ]
15
+ header = { "Content-Type" => "text/html;charset=utf-8",
16
+ "Content-Length" => content_length(body).to_s,
17
+ "X-XSS-Protection" => "1; mode=block",
18
+ "X-Content-Type-Options" => "nosniff",
19
+ "X-Frame-Options" => "SAMEORIGIN" }
20
+ [code, header, body]
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def self.view
27
+ File.read(filepath)
28
+ end
29
+
30
+ private
31
+
32
+ def self.filepath
33
+ File.join(VIEW_DIRECTORY, VIEW_FILE_NAME)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ module Facemock
2
+ module OAuth
3
+ class LoginHook < RackMiddleware
4
+ DEFAULT_PATH = "/sign_in"
5
+ @path = DEFAULT_PATH
6
+
7
+ def call(env)
8
+ res = super
9
+ if env["PATH_INFO"] == LoginHook.path
10
+ code = 302
11
+ body = []
12
+ header = { "Content-Type" => "text/html;charset=utf-8",
13
+ "Location" => location(env, "/facemock/sign_in"),
14
+ "Content-Length" => content_length(body).to_s,
15
+ "X-XSS-Protection" => "1; mode=block",
16
+ "X-Content-Type-Options" => "nosniff",
17
+ "X-Frame-Options" => "SAMEORIGIN" }
18
+ res = [ code, header, body ]
19
+ end
20
+ res
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ require 'rack'
2
+
3
+ module Facemock
4
+ module OAuth
5
+ class RackMiddleware
6
+ class << self
7
+ attr_accessor :path
8
+ end
9
+
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ @app.call(env)
16
+ end
17
+
18
+ private
19
+
20
+ def content_length(body)
21
+ body.inject(0) do |sum, content|
22
+ sum + content.bytesize
23
+ end
24
+ end
25
+
26
+ def location(env, path, query={})
27
+ scheme = env["rack.url_scheme"]
28
+ host = env["HTTP_HOST"]
29
+ query_string = ""
30
+ query_string = "?" + hash_to_query_string(query) unless query.empty?
31
+ url = scheme + "://" + host + path + query_string
32
+ end
33
+
34
+ def query_string_to_hash(query_string)
35
+ query_string.split("&").inject({}) do |hash, str|
36
+ key, value = str.split("=")
37
+ hash[key] = value
38
+ hash
39
+ end
40
+ end
41
+
42
+ def hash_to_query_string(query)
43
+ query_strings = query.inject([]) do |ary, (key,value)|
44
+ ary << "#{key}=#{value}"
45
+ end
46
+ query_strings.join("&")
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ module Facemock
2
+ module OAuth
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+
4
+ describe Facemock::OAuth::Authentication do
5
+ include Rack::Test::Methods
6
+ include TestApplicationHelper
7
+
8
+ let(:test_app) { TestApplicationHelper::TestRackApplication }
9
+ let(:app) { Facemock::OAuth::Authentication.new(test_app.new) }
10
+ let(:path) { '/facemock/oauth' }
11
+ let(:failed_path) { '/facemock/sign_in' }
12
+ let(:email) { 'test@example.org' }
13
+ let(:password) { 'password' }
14
+ let(:body) { "email=#{email}&pass=#{password}" }
15
+ let(:content_type) { 'application/x-www-form-urlencoded' }
16
+ let(:header) { { 'CONTENT_TYPE' => content_type } }
17
+
18
+ describe '::DEFAULT_PATH' do
19
+ subject { Facemock::OAuth::Authentication::DEFAULT_PATH }
20
+ it { is_expected.to eq path }
21
+ end
22
+
23
+ describe '.path' do
24
+ subject { Facemock::OAuth::Authentication.path }
25
+ it { is_expected.to eq path }
26
+ end
27
+
28
+ describe "GET '/'", assert: :RequestSuccess do
29
+ before { @path = '/' }
30
+ end
31
+
32
+ describe "GET '/facemock/oauth'", assert: :RequestSuccess do
33
+ before { @path = path }
34
+ end
35
+
36
+ shared_context '302 Found OAuth Callback', assert: :RedirectToOAuthCallback do
37
+ it 'should return 302 Found that location path is Facemock::OAuth::CallbackHook.path' do
38
+ post @path, body, header
39
+ expect(last_response.status).to eq 302
40
+ expect(last_response.body).to be_empty
41
+ expect(last_response.header["Content-Type"]).to eq "text/html;charset=utf-8"
42
+ expect(last_response.header["Content-Length"]).to eq "0"
43
+ expect(last_response.header["X-XSS-Protection"]).to eq "1; mode=block"
44
+ expect(last_response.header["X-Content-Type-Options"]).to eq "nosniff"
45
+ expect(last_response.header["X-Frame-Options"]).to eq "SAMEORIGIN"
46
+ code = @authorization_code.string
47
+ expect_url = "http://example.org" + Facemock::OAuth::CallbackHook.path + "?code=#{code}"
48
+ expect(last_response.header["Location"]).to eq expect_url
49
+ end
50
+ end
51
+
52
+ describe "POST '/facemock/oauth'" do
53
+ context 'when user does not found by email' do
54
+ it "should return 302 Found that location path is '/facemock/sign_in'" do
55
+ post path, body, header
56
+ expect(last_response.status).to eq 302
57
+ expect(last_response.body).to be_empty
58
+ expect(last_response.header["Content-Type"]).to eq "text/html;charset=utf-8"
59
+ expect(last_response.header["Content-Length"]).to eq "0"
60
+ expect(last_response.header["X-XSS-Protection"]).to eq "1; mode=block"
61
+ expect(last_response.header["X-Content-Type-Options"]).to eq "nosniff"
62
+ expect(last_response.header["X-Frame-Options"]).to eq "SAMEORIGIN"
63
+ expect(last_response.header["Location"]).to eq "http://example.org" + failed_path
64
+ end
65
+ end
66
+
67
+ context 'when user found', assert: :RedirectToOAuthCallback do
68
+ before do
69
+ @user = Facemock::Database::User.new({id: 1, email: email, password: password})
70
+ allow(Facemock::Database::User).to receive(:find_by_email) { @user }
71
+ @authorization_code = Facemock::Database::AuthorizationCode.new(user_id: @user.id)
72
+ allow(Facemock::Database::AuthorizationCode).to receive(:create!) { @authorization_code }
73
+ @path = path
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "POST '/test'" do
79
+ context "with correct body when path variable set '/test'", assert: :RedirectToOAuthCallback do
80
+ before do
81
+ @path = "/test"
82
+ Facemock::OAuth::Authentication.path = @path
83
+
84
+ @user = Facemock::Database::User.new({id: 1, email: email, password: password})
85
+ allow(Facemock::Database::User).to receive(:find_by_email) { @user }
86
+ @authorization_code = Facemock::Database::AuthorizationCode.new(user_id: @user.id)
87
+ allow(Facemock::Database::AuthorizationCode).to receive(:create!) { @authorization_code }
88
+ end
89
+ after { Facemock::OAuth::Authentication.path = path }
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+
4
+ describe Facemock::OAuth::CallbackHook do
5
+ include Rack::Test::Methods
6
+ include TestApplicationHelper
7
+
8
+ let(:test_app) { TestApplicationHelper::TestRackApplication }
9
+ let(:app) { Facemock::OAuth::CallbackHook.new(test_app.new) }
10
+ let(:path) { '/users/auth/callback' }
11
+
12
+ describe '::DEFAULT_PATH' do
13
+ subject { Facemock::OAuth::CallbackHook::DEFAULT_PATH }
14
+ it { is_expected.to eq path }
15
+ end
16
+
17
+ describe '.path' do
18
+ subject { Facemock::OAuth::CallbackHook.path }
19
+ it { is_expected.to eq path }
20
+ end
21
+
22
+ describe "GET '/'", assert: :RequestSuccess do
23
+ before { @path = '/' }
24
+ end
25
+
26
+ shared_context '200 OK and with AuthHash', assert: :SetAuthHash do
27
+ it 'should return 302 Found' do
28
+ get @path, code: @authorization_code.string
29
+ expect(last_response.status).to eq 200
30
+ expect(last_response.body).not_to be_nil
31
+ expect(last_response.header).not_to be_empty
32
+ expect(last_request.env['omniauth.auth']).to be_kind_of Facemock::AuthHash
33
+ expect(last_request.env['omniauth.auth']).not_to be_empty
34
+ expect(last_request.env['omniauth.auth']['provider']).to eq "facebook"
35
+ expect(last_request.env['omniauth.auth']['uid']).to eq @user.id
36
+ end
37
+ end
38
+
39
+ describe "GET '/users/auth/callback'" do
40
+ context 'without code parameter', assert: :RequestSuccess do
41
+ before { @path = '/' }
42
+ end
43
+
44
+ context 'with code parameter' do
45
+ before do
46
+ @user = Facemock::Database::User.new({ id: 1, access_token: "test_token" })
47
+ @authorization_code = Facemock::Database::AuthorizationCode.new(user_id: @user.id)
48
+ end
49
+
50
+ context 'when authorization code does not found', assert: :RequestSuccess do
51
+ before do
52
+ allow(Facemock::Database::AuthorizationCode).to receive(:find_by_string) { nil }
53
+ @path = path + "?code=#{@authorization_code.string}"
54
+ end
55
+ end
56
+
57
+ context 'when authorization code found but user does not found', assert: :RequestSuccess do
58
+ before do
59
+ allow(Facemock::Database::AuthorizationCode).to receive(:find_by_string) { @authorization_code }
60
+ allow(Facemock::Database::User).to receive(:find_by_id) { nil }
61
+ @path = path + "?code=#{@authorization_code.string}"
62
+ end
63
+ end
64
+
65
+ context 'when authorization code found by code parameter', assert: :SetAuthHash do
66
+ before do
67
+ allow(Facemock::Database::AuthorizationCode).to receive(:find_by_string) { @authorization_code }
68
+ allow(Facemock::Database::User).to receive(:find_by_id) { @user }
69
+ allow(Facemock::Database::User).to receive(:find_by_access_token) { @user }
70
+ @path = path
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "GET '/test'" do
77
+ context "when path variable set '/test'", assert: :SetAuthHash do
78
+ before do
79
+ @path = "/test"
80
+ Facemock::OAuth::CallbackHook.path = @path
81
+
82
+ @user = Facemock::Database::User.new({ id: 1, access_token: "test_token" })
83
+ @authorization_code = Facemock::Database::AuthorizationCode.new(user_id: @user.id)
84
+ allow(Facemock::Database::AuthorizationCode).to receive(:find_by_string) { @authorization_code }
85
+ allow(Facemock::Database::User).to receive(:find_by_id) { @user }
86
+ allow(Facemock::Database::User).to receive(:find_by_access_token) { @user }
87
+ end
88
+ after { Facemock::OAuth::CallbackHook.path = path }
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+
4
+ describe Facemock::OAuth::LoginHook do
5
+ include Rack::Test::Methods
6
+ include TestApplicationHelper
7
+
8
+ let(:test_app) { TestApplicationHelper::TestRackApplication }
9
+ let(:app) { Facemock::OAuth::LoginHook.new(test_app.new) }
10
+ let(:path) { "/sign_in" }
11
+
12
+ describe '::DEFAULT_PATH' do
13
+ subject { Facemock::OAuth::LoginHook::DEFAULT_PATH }
14
+ it { is_expected.to eq path }
15
+ end
16
+
17
+ describe '.path' do
18
+ subject { Facemock::OAuth::LoginHook.path }
19
+ it { is_expected.to eq path }
20
+ end
21
+
22
+ describe '.path=' do
23
+ context 'with "/test"' do
24
+ before { @path = "/test" }
25
+ after { Facemock::OAuth::LoginHook.path = path }
26
+
27
+ it 'should set class instance variable path' do
28
+ Facemock::OAuth::LoginHook.path = @path
29
+ expect(Facemock::OAuth::LoginHook.path).to eq @path
30
+ end
31
+ end
32
+ end
33
+
34
+ shared_context '302 Found Signin', assert: :RedirectToFacemockSignin do
35
+ it 'should return 302 Found' do
36
+ get @path
37
+ expect(last_response.status).to eq 302
38
+ expect(last_response.body).to be_empty
39
+ expect(last_response.header["Content-Type"]).to eq "text/html;charset=utf-8"
40
+ expect(last_response.header["Content-Length"]).to eq "0"
41
+ expect(last_response.header["X-XSS-Protection"]).to eq "1; mode=block"
42
+ expect(last_response.header["X-Content-Type-Options"]).to eq "nosniff"
43
+ expect(last_response.header["X-Frame-Options"]).to eq "SAMEORIGIN"
44
+ end
45
+ end
46
+
47
+ describe "GET '/'", assert: :RequestSuccess do
48
+ before { @path = '/' }
49
+ end
50
+
51
+ describe "GET '/facebook/sign_in'" do
52
+ context 'when path is default value', assert: :RedirectToFacemockSignin do
53
+ before { @path = path }
54
+ end
55
+
56
+ context 'when path variable set ather path', assert: :RequestSuccess do
57
+ before do
58
+ @path = path
59
+ Facemock::OAuth::LoginHook.path = "/test"
60
+ end
61
+ after { Facemock::OAuth::LoginHook.path = path }
62
+ end
63
+ end
64
+
65
+ describe "GET '/test'" do
66
+ context "when path variable set '/test'", assert: :RedirectToFacemockSignin do
67
+ before do
68
+ @path = "/test"
69
+ Facemock::OAuth::LoginHook.path = @path
70
+ end
71
+ after { Facemock::OAuth::LoginHook.path = path }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+
4
+ describe Facemock::OAuth::Login do
5
+ include Rack::Test::Methods
6
+ include TestApplicationHelper
7
+
8
+ let(:test_app) { TestApplicationHelper::TestRackApplication }
9
+ let(:app) { Facemock::OAuth::Login.new(test_app.new) }
10
+ let(:path) { "/facemock/sign_in" }
11
+
12
+ describe '::DEFAULT_PATH' do
13
+ subject { Facemock::OAuth::Login::DEFAULT_PATH }
14
+ it { is_expected.to eq path }
15
+ end
16
+
17
+ describe '.path' do
18
+ subject { Facemock::OAuth::Login.path }
19
+ it { is_expected.to eq path }
20
+ end
21
+
22
+ describe '.path=' do
23
+ context 'with "/test"' do
24
+ before { @path = "/test" }
25
+ after { Facemock::OAuth::Login.path = path }
26
+
27
+ it 'should set class instance variable path' do
28
+ Facemock::OAuth::Login.path = @path
29
+ expect(Facemock::OAuth::Login.path).to eq @path
30
+ end
31
+ end
32
+ end
33
+
34
+ shared_context '200 OK Signin View', assert: :GetFacemockLoginHtml do
35
+ it 'should return 200 OK' do
36
+ html = Facemock::OAuth::Login.view
37
+ get @path
38
+ expect(last_response.status).to eq 200
39
+ expect(last_response.body).to eq html
40
+ expect(last_response.header["Content-Type"]).to eq "text/html;charset=utf-8"
41
+ expect(last_response.header["Content-Length"]).to eq html.bytesize.to_s
42
+ expect(last_response.header["X-XSS-Protection"]).to eq "1; mode=block"
43
+ expect(last_response.header["X-Content-Type-Options"]).to eq "nosniff"
44
+ expect(last_response.header["X-Frame-Options"]).to eq "SAMEORIGIN"
45
+ end
46
+ end
47
+
48
+ describe "GET '/'", assert: :RequestSuccess do
49
+ before { @path = '/' }
50
+ end
51
+
52
+ describe "GET '/facemock/sign_in'", assert: :GetFacemockLoginHtml do
53
+ before { @path = path }
54
+ end
55
+
56
+ describe "GET '/test'" do
57
+ context "when path variable set '/test'", assert: :GetFacemockLoginHtml do
58
+ before do
59
+ @path = "/test"
60
+ Facemock::OAuth::Login.path = @path
61
+ end
62
+ after { Facemock::OAuth::Login.path = path }
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'rack/test'
3
+
4
+ describe Facemock::OAuth::RackMiddleware do
5
+ include Rack::Test::Methods
6
+ include TestApplicationHelper
7
+
8
+ let(:test_app) { TestApplicationHelper::TestRackApplication }
9
+ let(:app) { Facemock::OAuth::RackMiddleware.new(test_app.new) }
10
+
11
+ describe "GET '/'", assert: :RequestSuccess do
12
+ before { @path = '/' }
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Facemock::OAuth do
4
+ let(:version) { '0.0.1' }
5
+
6
+ it 'should have a version number' do
7
+ expect(Facemock::OAuth::VERSION).to eq version
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'simplecov'
4
+ require 'coveralls'
5
+
6
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
7
+ SimpleCov::Formatter::HTMLFormatter,
8
+ Coveralls::SimpleCov::Formatter
9
+ ]
10
+ SimpleCov.start do
11
+ add_filter '.bundle/'
12
+ add_filter '/spec/'
13
+ end
14
+
15
+ Dir[File.expand_path('../support/', __FILE__) + "/**/*.rb"].each {|f| require f}
16
+
17
+ require 'facemock/oauth'
@@ -0,0 +1,10 @@
1
+ module RackMiddlewareSpecHelper
2
+ shared_context "200 OK", assert: :RequestSuccess do
3
+ it 'should return 200 OK' do
4
+ get @path
5
+ expect(last_response.status).to eq 200
6
+ expect(last_response.body).not_to be_nil
7
+ expect(last_response.header).not_to be_empty
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ module TestApplicationHelper
2
+ extend self
3
+
4
+ class TestRackApplication
5
+ def call(env)
6
+ code = 200
7
+ body = [ "test body" ]
8
+ header = { "Content-Type" => "text/html;charset=utf-8",
9
+ "Content-Length" => "9",
10
+ "X-XSS-Protection" => "1; mode=block",
11
+ "X-Content-Type-Options" => "nosniff",
12
+ "X-Frame-Options" => "SAMEORIGIN" }
13
+ [ code, header, body ]
14
+ end
15
+ end
16
+ end
data/view/login.html ADDED
@@ -0,0 +1,59 @@
1
+ <!DOCTYPE html>
2
+ <html lang="ja" id="facemock" class>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title id="pageTitle">Facemock</title>
6
+ </head>
7
+ <body>
8
+ <div class="_li">
9
+ <a class="lfloat _ohe" href="/" title="hydrangeaトップへ移動">Top</a>
10
+ <div id="globalContainer" class="uiContextualLayerParent">
11
+ <div id="content" class="fb_content clearfix">
12
+ <div class="UIFullPage_Container">
13
+ <div class="mvl ptm uiInterstitial login_page_interstitial uiInterstitialLarge uiBoxWhite">
14
+ <div class="uiHeader uiHeaderBottomBorder mhl mts uiHeaderPage interstitialHeader">
15
+ <div class="clearfix uiHeaderTop">
16
+ <div class="uiHeader uiHeaderBottomBorder mhl mts uiHeaderPage interstitialHeader">
17
+ <h2 class="accessible_elem">Facemockログイン</h2>
18
+ </div>
19
+ <div class="phl ptm uiInterstitialContent">
20
+ <div class="login_form_container">
21
+ <form id="login_form" accept-charset="UTF-8" action="/facemock/oauth" method="post">
22
+ <input type="hidden" name="lsd" value="AVo09EiL" autocomplete="off">
23
+ <div class="hidden_elem"></div>
24
+ <div id="loginform">
25
+ <div class="form_row clearfix">
26
+ <label for="email" class="login_form_label">メールまたは電話番号:</label>
27
+ <input type="text" class="inputtext" id="email" name="email" value="">
28
+ </div>
29
+ <div class="form_row clearfix">
30
+ <label for="pass" class="login_form_label">パスワード:</label>
31
+ <input type="password" name="pass" id="pass" class="inputpassword">
32
+ </div>
33
+ <div class="persistent">
34
+ <div class="uiInputLabel clearfix uiInputLabelLegacy">
35
+ <input id="persist_box" type="checkbox" value="1" checked="1" name="persistent" class="uiInputLabelInput uiInputLabelCheckbox">
36
+ <label for="persist_box" class="uiInputLabelLabel">ログインしたままにする</label>
37
+ </div>
38
+ </div>
39
+ <div id="buttons" class="form_row clearfix">
40
+ <label class="login_form_label"></label>
41
+ <div id="login_button_inline">
42
+ <label class="uiButton uiButtonConfirm uiButtonLarge" id="loginbutton" for="u_0_1">
43
+ <input value="ログイン" name="login" type="submit" id="u_0_1">
44
+ </label>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </form>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </body>
59
+ </html>
metadata ADDED
@@ -0,0 +1,231 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: facemock-oauth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ogawatti
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: facemock
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rack
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rack-test
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: simplecov
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: coveralls
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: pry
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ description: This gem will mock the oauth of facebook using facemock.
159
+ email:
160
+ - ogawattim@gmail.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .coveralls.yml
166
+ - .gitignore
167
+ - .rspec
168
+ - .travis.yml
169
+ - Gemfile
170
+ - LICENSE.txt
171
+ - README.md
172
+ - Rakefile
173
+ - facemock-oauth.gemspec
174
+ - lib/facemock/oauth.rb
175
+ - lib/facemock/oauth/authentication.rb
176
+ - lib/facemock/oauth/callback_hook.rb
177
+ - lib/facemock/oauth/login.rb
178
+ - lib/facemock/oauth/login_hook.rb
179
+ - lib/facemock/oauth/rack_middleware.rb
180
+ - lib/facemock/oauth/version.rb
181
+ - spec/facemock/oauth/authentication_spec.rb
182
+ - spec/facemock/oauth/callback_hook_spec.rb
183
+ - spec/facemock/oauth/login_hook_spec.rb
184
+ - spec/facemock/oauth/login_spec.rb
185
+ - spec/facemock/oauth/rack_middleware_spec.rb
186
+ - spec/facemock/oauth_spec.rb
187
+ - spec/spec_helper.rb
188
+ - spec/support/last_response_spec_helper.rb
189
+ - spec/support/test_application_helper.rb
190
+ - view/login.html
191
+ homepage: https://github.com/ogawatti/facemock-oauth
192
+ licenses:
193
+ - MIT
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ segments:
205
+ - 0
206
+ hash: 1427437800597443227
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - ! '>='
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ segments:
214
+ - 0
215
+ hash: 1427437800597443227
216
+ requirements: []
217
+ rubyforge_project:
218
+ rubygems_version: 1.8.25
219
+ signing_key:
220
+ specification_version: 3
221
+ summary: This is facebook oauth mock application.
222
+ test_files:
223
+ - spec/facemock/oauth/authentication_spec.rb
224
+ - spec/facemock/oauth/callback_hook_spec.rb
225
+ - spec/facemock/oauth/login_hook_spec.rb
226
+ - spec/facemock/oauth/login_spec.rb
227
+ - spec/facemock/oauth/rack_middleware_spec.rb
228
+ - spec/facemock/oauth_spec.rb
229
+ - spec/spec_helper.rb
230
+ - spec/support/last_response_spec_helper.rb
231
+ - spec/support/test_application_helper.rb