danski-ooh-auth 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/Rakefile +58 -0
- data/app/controllers/application.rb +16 -0
- data/app/controllers/authenticating_clients.rb +60 -0
- data/app/controllers/tokens.rb +94 -0
- data/app/helpers/application_helper.rb +64 -0
- data/app/helpers/authenticating_clients_helper.rb +5 -0
- data/app/helpers/authentications_helper.rb +5 -0
- data/app/models/authenticating_client.rb +12 -0
- data/app/models/authenticating_client/dm_authenticating_client.rb +71 -0
- data/app/models/token.rb +12 -0
- data/app/models/token/dm_token.rb +150 -0
- data/app/views/authenticating_clients/_help.html.erb +1 -0
- data/app/views/authenticating_clients/edit.html.erb +27 -0
- data/app/views/authenticating_clients/index.html.erb +24 -0
- data/app/views/authenticating_clients/new.html.erb +47 -0
- data/app/views/authenticating_clients/show.html.erb +40 -0
- data/app/views/layout/ooh_auth.html.erb +23 -0
- data/app/views/tokens/create.html.erb +34 -0
- data/app/views/tokens/edit.html.erb +4 -0
- data/app/views/tokens/new.html.erb +52 -0
- data/app/views/tokens/show.html.erb +1 -0
- data/lib/ooh-auth.rb +103 -0
- data/lib/ooh-auth/authentication_mixin.rb +13 -0
- data/lib/ooh-auth/controller_mixin.rb +38 -0
- data/lib/ooh-auth/key_generators.rb +57 -0
- data/lib/ooh-auth/merbtasks.rb +103 -0
- data/lib/ooh-auth/request_verification_mixin.rb +160 -0
- data/lib/ooh-auth/slicetasks.rb +18 -0
- data/lib/ooh-auth/spectasks.rb +65 -0
- data/lib/ooh-auth/strategies/oauth.rb +16 -0
- data/public/javascripts/master.js +0 -0
- data/public/stylesheets/master.css +2 -0
- data/readme.markdown +43 -0
- data/spec/controllers/application_spec.rb +35 -0
- data/spec/controllers/authenticating_clients_spec.rb +119 -0
- data/spec/controllers/tokens_spec.rb +173 -0
- data/spec/merb-auth-slice-fullfat_spec.rb +41 -0
- data/spec/models/authenticating_client_spec.rb +44 -0
- data/spec/models/oauth_strategy_spec.rb +48 -0
- data/spec/models/request_verification_mixin_spec.rb +121 -0
- data/spec/models/token_spec.rb +139 -0
- data/spec/spec_fixtures.rb +19 -0
- data/spec/spec_helper.rb +107 -0
- data/stubs/app/controllers/application.rb +2 -0
- data/stubs/app/controllers/main.rb +2 -0
- metadata +133 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
namespace :slices do
|
2
|
+
namespace :ooh_auth do
|
3
|
+
|
4
|
+
desc "Install OohAuth"
|
5
|
+
task :install => [:preflight, :setup_directories, :copy_assets, :migrate]
|
6
|
+
|
7
|
+
desc "Test for any dependencies"
|
8
|
+
task :preflight do # see slicetasks.rb
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Setup directories"
|
12
|
+
task :setup_directories do
|
13
|
+
puts "Creating directories for host application"
|
14
|
+
OohAuth.mirrored_components.each do |type|
|
15
|
+
if File.directory?(OohAuth.dir_for(type))
|
16
|
+
if !File.directory?(dst_path = OohAuth.app_dir_for(type))
|
17
|
+
relative_path = dst_path.relative_path_from(Merb.root)
|
18
|
+
puts "- creating directory :#{type} #{File.basename(Merb.root) / relative_path}"
|
19
|
+
mkdir_p(dst_path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Copy stub files to host application"
|
26
|
+
task :stubs do
|
27
|
+
puts "Copying stubs for OohAuth - resolves any collisions"
|
28
|
+
copied, preserved = OohAuth.mirror_stubs!
|
29
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
30
|
+
copied.each { |f| puts "- copied #{f}" }
|
31
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Copy stub files and views to host application"
|
35
|
+
task :patch => [ "stubs", "freeze:views" ]
|
36
|
+
|
37
|
+
desc "Copy public assets to host application"
|
38
|
+
task :copy_assets do
|
39
|
+
puts "Copying assets for OohAuth - resolves any collisions"
|
40
|
+
copied, preserved = OohAuth.mirror_public!
|
41
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
42
|
+
copied.each { |f| puts "- copied #{f}" }
|
43
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Migrate the database"
|
47
|
+
task :migrate do # see slicetasks.rb
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Freeze OohAuth into your app (only ooh-auth/app)"
|
51
|
+
task :freeze => [ "freeze:app" ]
|
52
|
+
|
53
|
+
namespace :freeze do
|
54
|
+
|
55
|
+
desc "Freezes OohAuth by installing the gem into application/gems"
|
56
|
+
task :gem do
|
57
|
+
ENV["GEM"] ||= "ooh-auth"
|
58
|
+
Rake::Task['slices:install_as_gem'].invoke
|
59
|
+
end
|
60
|
+
|
61
|
+
desc "Freezes OohAuth by copying all files from ooh-auth/app to your application"
|
62
|
+
task :app do
|
63
|
+
puts "Copying all ooh-auth/app files to your application - resolves any collisions"
|
64
|
+
copied, preserved = OohAuth.mirror_app!
|
65
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
66
|
+
copied.each { |f| puts "- copied #{f}" }
|
67
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Freeze all views into your application for easy modification"
|
71
|
+
task :views do
|
72
|
+
puts "Copying all view templates to your application - resolves any collisions"
|
73
|
+
copied, preserved = OohAuth.mirror_files_for :view
|
74
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
75
|
+
copied.each { |f| puts "- copied #{f}" }
|
76
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Freeze all models into your application for easy modification"
|
80
|
+
task :models do
|
81
|
+
puts "Copying all models to your application - resolves any collisions"
|
82
|
+
copied, preserved = OohAuth.mirror_files_for :model
|
83
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
84
|
+
copied.each { |f| puts "- copied #{f}" }
|
85
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "Freezes OohAuth as a gem and copies over ooh-auth/app"
|
89
|
+
task :app_with_gem => [:gem, :app]
|
90
|
+
|
91
|
+
desc "Freezes OohAuth by unpacking all files into your application"
|
92
|
+
task :unpack do
|
93
|
+
puts "Unpacking OohAuth files to your application - resolves any collisions"
|
94
|
+
copied, preserved = OohAuth.unpack_slice!
|
95
|
+
puts "- no files to copy" if copied.empty? && preserved.empty?
|
96
|
+
copied.each { |f| puts "- copied #{f}" }
|
97
|
+
preserved.each { |f| puts "! preserved override as #{f}" }
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
=begin
|
2
|
+
OohAuth::Request::VerificationMixin is a mixin module for Merb's internal Request class.
|
3
|
+
|
4
|
+
It provides
|
5
|
+
=end
|
6
|
+
|
7
|
+
require 'hmac-sha1'
|
8
|
+
require 'hmac-md5'
|
9
|
+
|
10
|
+
module OohAuth
|
11
|
+
module Request
|
12
|
+
module VerificationMixin
|
13
|
+
|
14
|
+
# Returns TRUE if the request contains api-flavour parameters. At least an api_token and an api_signature must be present
|
15
|
+
def oauth_request?
|
16
|
+
(consumer_key)? true : false
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the authenticating client referenced by the consumer key in the given request, or nil if
|
20
|
+
# no consumer key was given or if the given consumer key was invalid.
|
21
|
+
def authenticating_client
|
22
|
+
#return false unless signed?
|
23
|
+
@authenticating_client ||= OohAuth::AuthenticatingClient.first(:api_key=>consumer_key)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the stored token referenced by the oauth_token header or parameter, or nil if none was found.
|
27
|
+
def authentication_token
|
28
|
+
@authentication_token ||= OohAuth::Token.first(:token_key=>token)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Attempts to verify the request's signature using the strategy covered in signing.markdown.
|
32
|
+
# Takes one argument, which is the authenticating client you wish to check the signature against.
|
33
|
+
# Returns a true on success, false on fail.
|
34
|
+
def signed?
|
35
|
+
# Fail immediately if the request is not signed at all
|
36
|
+
return false unless oauth_request? and authenticating_client
|
37
|
+
# mash and compare with given signature
|
38
|
+
self.signature == build_signature
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates a signature for this request, returning the final hash required for insertion in a signed URL.
|
42
|
+
def build_signature
|
43
|
+
sig = case signature_method
|
44
|
+
when "HMAC-SHA1"
|
45
|
+
Base64.encode64(HMAC::SHA1.digest(signature_secret, signature_base_string)).chomp.gsub(/\n/,'')
|
46
|
+
when "HMAC-MD5"
|
47
|
+
Base64.encode64(HMAC::MD5.digest(signature_secret, signature_base_string)).chomp.gsub(/\n/,'')
|
48
|
+
else
|
49
|
+
false
|
50
|
+
end
|
51
|
+
Merb::Parse.escape(sig)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Creates a plaintext version of the signature base string ready to be run through any#
|
55
|
+
# of the support OAuth signature methods.
|
56
|
+
# See http://oauth.net/core/1.0#signing_process for more information.
|
57
|
+
def signature_base_string
|
58
|
+
"#{method.to_s.upcase}&#{full_uri}&#{normalise_signature_params}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the signature secret, which is expected to be the HMAC encryption key for signed requests.
|
62
|
+
# If the request refers to a token, the token will be retrieved
|
63
|
+
def signature_secret
|
64
|
+
"#{authenticating_client.secret}&#{authentication_token ? authentication_token.secret : nil}" rescue raise Merb::ControllerExceptions::NotAcceptable
|
65
|
+
end
|
66
|
+
|
67
|
+
# Scrubs route parameters from the known params, returning a hash of known GET and POST parameters.
|
68
|
+
# Basically, this returns the parameters needed in the signature key/value gibberish.
|
69
|
+
# FIXME unidentified request gremlins seeding params with mix of symbol and string keys, requiring to_s filth all over the match block.
|
70
|
+
def signature_params
|
71
|
+
route, route_params = Merb::Router.route_for(self)
|
72
|
+
#raise RuntimeError, route_params.inspect
|
73
|
+
return oauth_merged_params.delete_if {|k,v| route_params.keys.map{|s|s.to_s}.include?(k.to_s) or k.to_s == "oauth_signature"}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the signature_params as a normalised string in line with
|
77
|
+
# http://oauth.net/core/1.0#signing_process
|
78
|
+
def normalise_signature_params
|
79
|
+
signature_params.sort.collect{|key, value| "#{key}=#{value}"}.join("&")
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the params properly merged with the oauth headers if they were given.
|
83
|
+
# OAuth headers take priority if a GET/POST parameter with the same name exists.
|
84
|
+
def oauth_merged_params
|
85
|
+
params.merge(signature_oauth_headers)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns any given OAuth headers as specified in http://oauth.net/core/1.0#auth_header as a hash.
|
89
|
+
def oauth_headers
|
90
|
+
@oauth_headers ||= parse_oauth_headers
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the auth headers for duplicating the request signature,
|
94
|
+
# missing the realm variable as defined in
|
95
|
+
# http://oauth.net/core/1.0#signing_process
|
96
|
+
def signature_oauth_headers
|
97
|
+
o = oauth_headers.dup; o.delete(:realm); o
|
98
|
+
end
|
99
|
+
|
100
|
+
# Parses the given OAuth headers into a hash. See http://oauth.net/core/1.0#auth_header for parsing method.
|
101
|
+
def parse_oauth_headers
|
102
|
+
# Pull headers and return blank hash if no header variables found
|
103
|
+
headers = env['AUTHORIZATION']; result = {};
|
104
|
+
return result unless headers && headers[0,5] == 'OAuth'
|
105
|
+
# Headers found. Go ahead and match 'em
|
106
|
+
headers.split(/,\n*\r*/).each do |param|
|
107
|
+
phrase, key, value = param.match(/([A-Za-z0-9_\s]+)="([^"]+)"/).to_a.map{|v| v.strip}
|
108
|
+
result[(key["OAuth"])? :realm : key.to_sym] = value
|
109
|
+
end
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
# OAuth variable accessors
|
116
|
+
# --------------------------------------------------------------------------------------------
|
117
|
+
|
118
|
+
# Returns the requested signature signing mechanism from the auth headers, defaulting to HMAC-SHA1
|
119
|
+
def signature_method
|
120
|
+
oauth_merged_params[:oauth_signature_method] || "HMAC-SHA1"
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns the oauth_consumer_key from the Authorization header or the GET/POST params, or nil if not present.
|
124
|
+
def consumer_key
|
125
|
+
oauth_merged_params[:oauth_consumer_key]
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns the oauth_token from the Authorization header or the GET/POST params, or nil if not present.
|
129
|
+
def token
|
130
|
+
oauth_merged_params[:oauth_token]
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns the oauth_signature from the Authorization header or the GET/POST params, or nil if not present.
|
134
|
+
def signature
|
135
|
+
# FIXME merb keeps mangling this by replacing "+" with "\s"
|
136
|
+
oauth_merged_params[:oauth_signature]
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns the oauth_timestamp from the Authorization header or the GET/POST params, or nil if not present.
|
140
|
+
def timestamp
|
141
|
+
oauth_merged_params[:oauth_timestamp]
|
142
|
+
end
|
143
|
+
|
144
|
+
# Returns the oauth_nonce from the Authorization header or the GET/POST params, or nil if not present.
|
145
|
+
def nonce
|
146
|
+
oauth_merged_params[:oauth_nonce]
|
147
|
+
end
|
148
|
+
|
149
|
+
def callback
|
150
|
+
oauth_merged_params[:oauth_callback]
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns the oauth_version from the Authorization header or the GET/POST params, or nil if not present, defaulting to "1.0" if not given.
|
154
|
+
def oauth_version
|
155
|
+
oauth_merged_params[:oauth_version] || "1.0"
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
namespace :slices do
|
2
|
+
namespace :ooh_auth do
|
3
|
+
|
4
|
+
# add your own ooh-auth tasks here
|
5
|
+
|
6
|
+
# implement this to test for structural/code dependencies
|
7
|
+
# like certain directories or availability of other files
|
8
|
+
desc "Test for any dependencies"
|
9
|
+
task :preflight do
|
10
|
+
end
|
11
|
+
|
12
|
+
# implement this to perform any database related setup steps
|
13
|
+
desc "Migrate the database"
|
14
|
+
task :migrate do
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
namespace :slices do
|
2
|
+
namespace :ooh_auth do
|
3
|
+
|
4
|
+
desc "Run slice specs within the host application context"
|
5
|
+
task :spec => [ "spec:explain", "spec:default" ]
|
6
|
+
|
7
|
+
namespace :spec do
|
8
|
+
|
9
|
+
slice_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
10
|
+
|
11
|
+
task :explain do
|
12
|
+
puts "\nNote: By running OohAuth specs inside the application context any\n" +
|
13
|
+
"overrides could break existing specs. This isn't always a problem,\n" +
|
14
|
+
"especially in the case of views. Use these spec tasks to check how\n" +
|
15
|
+
"well your application conforms to the original slice implementation."
|
16
|
+
end
|
17
|
+
|
18
|
+
Spec::Rake::SpecTask.new('default') do |t|
|
19
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
20
|
+
t.spec_files = Dir["#{slice_root}/spec/**/*_spec.rb"].sort
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Run all model specs, run a spec for a specific Model with MODEL=MyModel"
|
24
|
+
Spec::Rake::SpecTask.new('model') do |t|
|
25
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
26
|
+
if(ENV['MODEL'])
|
27
|
+
t.spec_files = Dir["#{slice_root}/spec/models/**/#{ENV['MODEL']}_spec.rb"].sort
|
28
|
+
else
|
29
|
+
t.spec_files = Dir["#{slice_root}/spec/models/**/*_spec.rb"].sort
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Run all controller specs, run a spec for a specific Controller with CONTROLLER=MyController"
|
34
|
+
Spec::Rake::SpecTask.new('controller') do |t|
|
35
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
36
|
+
if(ENV['CONTROLLER'])
|
37
|
+
t.spec_files = Dir["#{slice_root}/spec/controllers/**/#{ENV['CONTROLLER']}_spec.rb"].sort
|
38
|
+
else
|
39
|
+
t.spec_files = Dir["#{slice_root}/spec/controllers/**/*_spec.rb"].sort
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Run all view specs, run specs for a specific controller (and view) with CONTROLLER=MyController (VIEW=MyView)"
|
44
|
+
Spec::Rake::SpecTask.new('view') do |t|
|
45
|
+
t.spec_opts = ["--format", "specdoc", "--colour"]
|
46
|
+
if(ENV['CONTROLLER'] and ENV['VIEW'])
|
47
|
+
t.spec_files = Dir["#{slice_root}/spec/views/**/#{ENV['CONTROLLER']}/#{ENV['VIEW']}*_spec.rb"].sort
|
48
|
+
elsif(ENV['CONTROLLER'])
|
49
|
+
t.spec_files = Dir["#{slice_root}/spec/views/**/#{ENV['CONTROLLER']}/*_spec.rb"].sort
|
50
|
+
else
|
51
|
+
t.spec_files = Dir["#{slice_root}/spec/views/**/*_spec.rb"].sort
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Run all specs and output the result in html"
|
56
|
+
Spec::Rake::SpecTask.new('html') do |t|
|
57
|
+
t.spec_opts = ["--format", "html"]
|
58
|
+
t.libs = ['lib', 'server/lib' ]
|
59
|
+
t.spec_files = Dir["#{slice_root}/spec/**/*_spec.rb"].sort
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Authentication Strategy for OohAuth's AuthenticatingClient model.
|
2
|
+
|
3
|
+
class Merb::Authentication
|
4
|
+
module Strategies
|
5
|
+
class OAuth < Merb::Authentication::Strategy
|
6
|
+
|
7
|
+
def run!
|
8
|
+
if request.signed? and request.token and request.consumer_key
|
9
|
+
return OohAuth::Token.authenticate!(request.consumer_key, request.token)
|
10
|
+
end
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
|
14
|
+
end # APIToken
|
15
|
+
end # Strategies
|
16
|
+
end # MAuth
|
File without changes
|
data/readme.markdown
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
There's Auth, there's OAuth, and there's OohAuth.
|
2
|
+
=================================================
|
3
|
+
|
4
|
+
OohAuth extends merb-auth-more with a functionally-complete approach to OAuth, turning your merb-auth applications into full OAuth providers.
|
5
|
+
|
6
|
+
OAuth at a glance:
|
7
|
+
==================
|
8
|
+
|
9
|
+
* Your users won't have to give their names and passwords to client applications
|
10
|
+
* Your users can revoke or limit access from a particular client at any time
|
11
|
+
* Your users do not have to give client applications everything they need to steal their account
|
12
|
+
* Your developer community can authenticate using a solid authentication schema endorsed by [industry giants](http://google.com)
|
13
|
+
* Resilient to both man-in-the-middle and signature replay attacks.
|
14
|
+
|
15
|
+
OohAuth gives you:
|
16
|
+
========================
|
17
|
+
|
18
|
+
* Integration with merb-auth and your application's own User model
|
19
|
+
* RESTful creation of API keys for client apps
|
20
|
+
* RESTful creation of request and access tokens to allow client apps to authenticate on behalf of users
|
21
|
+
* merb-auth strategies for both web-based and non web-based API authentication.
|
22
|
+
|
23
|
+
It depends on:
|
24
|
+
==============
|
25
|
+
|
26
|
+
* merb-slices
|
27
|
+
* merb-action-args
|
28
|
+
* merb-auth-core
|
29
|
+
* merb-auth-more
|
30
|
+
* nokogiri (tests only)
|
31
|
+
* ruby-hmac
|
32
|
+
* Erb **(we need your help to get started on HAML support)**
|
33
|
+
* datamapper **(we need your help to become ORM-agnostic)**
|
34
|
+
|
35
|
+
You should read:
|
36
|
+
================
|
37
|
+
|
38
|
+
* [Why we wrote it](http://singlecell.angryamoeba.co.uk/post/62022487/the-api-antipattern-twitter-and-the-fail-whales-new)
|
39
|
+
* [OohAuth on github](http://github.com/danski/ooh-auth)
|
40
|
+
* [OAuth 1.0 specification](http://oauth.net/core/1.0) a hefty spec document containing instructions for authenticating with OAuth apps and more.
|
41
|
+
* [securing.markdown](http://github.com/danski/ooh-auth/tree/master/securing.markdown), your guide to properly securing an application using OohAuth.
|
42
|
+
* [OohAuth's bugtracker on Tails](http://www.bugtails.com/projects/171)
|
43
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe OohAuth::Application do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
Merb::Router.prepare { add_slice(:OohAuth) } if standalone?
|
7
|
+
@controller = dispatch_to(OohAuth::Public, :index)
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
Merb::Router.reset! if standalone?
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have access to the slice module" do
|
15
|
+
@controller.slice.should == OohAuth
|
16
|
+
@controller.slice.should == OohAuth::Public.slice
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have helper methods for dealing with public paths" do
|
20
|
+
@controller.public_path_for(:image).should == "/slices/ooh-auth/images"
|
21
|
+
@controller.public_path_for(:javascript).should == "/slices/ooh-auth/javascripts"
|
22
|
+
@controller.public_path_for(:stylesheet).should == "/slices/ooh-auth/stylesheets"
|
23
|
+
|
24
|
+
@controller.image_path.should == "/slices/ooh-auth/images"
|
25
|
+
@controller.javascript_path.should == "/slices/ooh-auth/javascripts"
|
26
|
+
@controller.stylesheet_path.should == "/slices/ooh-auth/stylesheets"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have a slice-specific _template_root" do
|
30
|
+
OohAuth::Public._template_root.should == OohAuth.dir_for(:view)
|
31
|
+
OohAuth::Public._template_root.should == OohAuth::Application._template_root
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|