merb-auth 0.1.0 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.textile +90 -0
- data/Rakefile +82 -38
- data/TODO +0 -0
- data/lib/merb-auth.rb +4 -72
- metadata +48 -50
- data/README +0 -64
- data/app/controllers/application.rb +0 -4
- data/app/controllers/controller_mixin.rb +0 -150
- data/app/controllers/users.rb +0 -41
- data/app/helpers/application_helper.rb +0 -64
- data/app/views/layout/merb_auth.html.erb +0 -47
- data/app/views/users/login.html.erb +0 -31
- data/app/views/users/signup.html.erb +0 -29
- data/lib/merb-auth/adapter/activerecord.rb +0 -52
- data/lib/merb-auth/adapter/datamapper.rb +0 -78
- data/lib/merb-auth/merbtasks.rb +0 -166
- data/lib/merb-auth/model.rb +0 -80
- data/lib/merb-auth/slicetasks.rb +0 -18
- data/public/stylesheets/master.css +0 -157
- data/spec/controllers/router_spec.rb +0 -29
- data/spec/controllers/session_spec.rb +0 -87
- data/spec/controllers/users_spec.rb +0 -41
- data/spec/controllers/view_helper_spec.rb +0 -27
- data/spec/merb-auth_spec.rb +0 -52
- data/spec/models/ar_user_spec.rb +0 -20
- data/spec/models/dm_user_spec.rb +0 -22
- data/spec/models/shared_user_spec.rb +0 -251
- data/spec/spec_helper.rb +0 -42
@@ -1,150 +0,0 @@
|
|
1
|
-
module MerbAuth
|
2
|
-
module ControllerMixin
|
3
|
-
protected
|
4
|
-
# Returns true or false if the user is logged in.
|
5
|
-
# Preloads @current_user with the user model if they're logged in.
|
6
|
-
def logged_in?
|
7
|
-
current_user != :false
|
8
|
-
end
|
9
|
-
|
10
|
-
# Accesses the current user from the session. Set it to :false if login fails
|
11
|
-
# so that future calls do not hit the database.
|
12
|
-
def current_user
|
13
|
-
@current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie || :false)
|
14
|
-
end
|
15
|
-
|
16
|
-
# Store the given user in the session.
|
17
|
-
def current_user=(new_user)
|
18
|
-
session[:user] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id
|
19
|
-
@current_user = new_user
|
20
|
-
end
|
21
|
-
|
22
|
-
# Check if the user is authorized
|
23
|
-
#
|
24
|
-
# Override this method in your controllers if you want to restrict access
|
25
|
-
# to only a few actions or if you want to check if the user
|
26
|
-
# has the correct rights.
|
27
|
-
#
|
28
|
-
# Example:
|
29
|
-
#
|
30
|
-
# # only allow nonbobs
|
31
|
-
# def authorized?
|
32
|
-
# current_user.username != "bob"
|
33
|
-
# end
|
34
|
-
def authorized?
|
35
|
-
logged_in?
|
36
|
-
end
|
37
|
-
|
38
|
-
# Filter method to enforce a login requirement.
|
39
|
-
#
|
40
|
-
# To require logins for all actions, use this in your controllers:
|
41
|
-
#
|
42
|
-
# before_filter :login_required
|
43
|
-
#
|
44
|
-
# To require logins for specific actions, use this in your controllers:
|
45
|
-
#
|
46
|
-
# before_filter :login_required, :only => [ :edit, :update ]
|
47
|
-
#
|
48
|
-
# To skip this in a subclassed controller:
|
49
|
-
#
|
50
|
-
# skip_before_filter :login_required
|
51
|
-
#
|
52
|
-
def login_required
|
53
|
-
authorized? || throw(:halt, :access_denied)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Redirect as appropriate when an access request fails.
|
57
|
-
#
|
58
|
-
# The default HTML action is to redirect to the login screen.
|
59
|
-
#
|
60
|
-
# The default XML action is to render the text Couldn't authenticate you.
|
61
|
-
# To provide this response wrapped in XML, make sure to specify an
|
62
|
-
# XML layout, such as /app/views/layouts/application.xml.builder.
|
63
|
-
#
|
64
|
-
# Override this method in your controllers if you want to have special
|
65
|
-
# behavior in case the user is not authorized
|
66
|
-
# to access the requested action. For example, a popup window might
|
67
|
-
# simply close itself.
|
68
|
-
def access_denied
|
69
|
-
case content_type
|
70
|
-
when :html
|
71
|
-
store_location
|
72
|
-
redirect url(:login)
|
73
|
-
when :xml
|
74
|
-
headers["Status"] = "Unauthorized"
|
75
|
-
headers["WWW-Authenticate"] = %(Basic realm="Web Password")
|
76
|
-
self.status = 401
|
77
|
-
render "Couldn't authenticate you"
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Store the URI of the current request in the session.
|
82
|
-
#
|
83
|
-
# We can return to this location by calling #redirect_back_or_default.
|
84
|
-
def store_location
|
85
|
-
session[:return_to] = request.uri
|
86
|
-
end
|
87
|
-
|
88
|
-
# Redirect to the URI stored by the most recent store_location call or
|
89
|
-
# to the passed default.
|
90
|
-
def redirect_back_or_default(default)
|
91
|
-
loc = session[:return_to] || default
|
92
|
-
session[:return_to] = nil
|
93
|
-
redirect loc
|
94
|
-
end
|
95
|
-
|
96
|
-
# Inclusion hook to make #current_user and #logged_in?
|
97
|
-
# available as ActionView helper methods.
|
98
|
-
# def self.included(base)
|
99
|
-
# base.send :helper_method, :current_user, :logged_in?
|
100
|
-
# end
|
101
|
-
|
102
|
-
# Called from #current_user. First attempt to login by the user id stored in the session.
|
103
|
-
def login_from_session
|
104
|
-
self.current_user = find_user_by_id(session[:user]) if session[:user]
|
105
|
-
end
|
106
|
-
|
107
|
-
# Called from #current_user. Now, attempt to login by basic authentication information.
|
108
|
-
def login_from_basic_auth
|
109
|
-
username, passwd = get_auth_data
|
110
|
-
self.current_user = verify_login(username, passwd) if username && passwd
|
111
|
-
end
|
112
|
-
|
113
|
-
# Called from #current_user. Finaly, attempt to login by an expiring token in the cookie.
|
114
|
-
def login_from_cookie
|
115
|
-
user = cookies[:auth_token] && find_user_by_remember_token(cookies[:auth_token])
|
116
|
-
if user && user.remember_token?
|
117
|
-
user.remember_me
|
118
|
-
cookies[:auth_token] = { :value => user.remember_token, :expires => Time.parse(user.remember_token_expires_at.strftime) }
|
119
|
-
self.current_user = user
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def reset_session
|
124
|
-
session.data.each{|k,v| session.data.delete(k)}
|
125
|
-
end
|
126
|
-
|
127
|
-
protected
|
128
|
-
def verify_login(username, password)
|
129
|
-
MerbAuth::User.authenticate(username, password)
|
130
|
-
end
|
131
|
-
|
132
|
-
def find_user_by_id(user_id)
|
133
|
-
MerbAuth::User.find_by_id(user_id)
|
134
|
-
end
|
135
|
-
|
136
|
-
def find_user_by_remember_token(token)
|
137
|
-
MerbAuth::User.find_by_remember_token(token)
|
138
|
-
end
|
139
|
-
|
140
|
-
private
|
141
|
-
@@http_auth_headers = %w(Authorization HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION X_HTTP_AUTHORIZATION REDIRECT_X_HTTP_AUTHORIZATION)
|
142
|
-
|
143
|
-
# gets BASIC auth info
|
144
|
-
def get_auth_data
|
145
|
-
auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
|
146
|
-
auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
|
147
|
-
return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
data/app/controllers/users.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
class MerbAuth::Users < MerbAuth::Application
|
2
|
-
provides :html
|
3
|
-
|
4
|
-
skip_before :login_required
|
5
|
-
|
6
|
-
def login
|
7
|
-
if request.post?
|
8
|
-
self.current_user = verify_login(params[:username], params[:password])
|
9
|
-
if logged_in?
|
10
|
-
if params[:remember_me] == "1"
|
11
|
-
self.current_user.remember_me
|
12
|
-
cookies[:auth_token] = {
|
13
|
-
:value => self.current_user.remember_token,
|
14
|
-
:expires => Time.parse(current_user.remember_token_expires_at.strftime)
|
15
|
-
}
|
16
|
-
end
|
17
|
-
return redirect_back_or_default('/')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
render
|
22
|
-
end
|
23
|
-
|
24
|
-
def logout
|
25
|
-
self.current_user.forget_me if logged_in?
|
26
|
-
cookies.delete :auth_token
|
27
|
-
reset_session
|
28
|
-
redirect_back_or_default('/')
|
29
|
-
end
|
30
|
-
|
31
|
-
def signup
|
32
|
-
cookies.delete :auth_token
|
33
|
-
@user = MerbAuth::User.new(params['merb_auth::user'] || {})
|
34
|
-
|
35
|
-
if request.post? && @user.save
|
36
|
-
return redirect_back_or_default('/')
|
37
|
-
end
|
38
|
-
|
39
|
-
render
|
40
|
-
end
|
41
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module Merb
|
2
|
-
module MerbAuth
|
3
|
-
module ApplicationHelper
|
4
|
-
|
5
|
-
# @param *segments<Array[#to_s]> Path segments to append.
|
6
|
-
#
|
7
|
-
# @return <String>
|
8
|
-
# A path relative to the public directory, with added segments.
|
9
|
-
def image_path(*segments)
|
10
|
-
public_path_for(:image, *segments)
|
11
|
-
end
|
12
|
-
|
13
|
-
# @param *segments<Array[#to_s]> Path segments to append.
|
14
|
-
#
|
15
|
-
# @return <String>
|
16
|
-
# A path relative to the public directory, with added segments.
|
17
|
-
def javascript_path(*segments)
|
18
|
-
public_path_for(:javascript, *segments)
|
19
|
-
end
|
20
|
-
|
21
|
-
# @param *segments<Array[#to_s]> Path segments to append.
|
22
|
-
#
|
23
|
-
# @return <String>
|
24
|
-
# A path relative to the public directory, with added segments.
|
25
|
-
def stylesheet_path(*segments)
|
26
|
-
public_path_for(:stylesheet, *segments)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Construct a path relative to the public directory
|
30
|
-
#
|
31
|
-
# @param <Symbol> The type of component.
|
32
|
-
# @param *segments<Array[#to_s]> Path segments to append.
|
33
|
-
#
|
34
|
-
# @return <String>
|
35
|
-
# A path relative to the public directory, with added segments.
|
36
|
-
def public_path_for(type, *segments)
|
37
|
-
File.join(::MerbAuth.public_dir_for(type), *segments)
|
38
|
-
end
|
39
|
-
|
40
|
-
# Construct an app-level path.
|
41
|
-
#
|
42
|
-
# @param <Symbol> The type of component.
|
43
|
-
# @param *segments<Array[#to_s]> Path segments to append.
|
44
|
-
#
|
45
|
-
# @return <String>
|
46
|
-
# A path within the host application, with added segments.
|
47
|
-
def app_path_for(type, *segments)
|
48
|
-
File.join(::MerbAuth.app_dir_for(type), *segments)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Construct a slice-level path.
|
52
|
-
#
|
53
|
-
# @param <Symbol> The type of component.
|
54
|
-
# @param *segments<Array[#to_s]> Path segments to append.
|
55
|
-
#
|
56
|
-
# @return <String>
|
57
|
-
# A path within the slice source (Gem), with added segments.
|
58
|
-
def slice_path_for(type, *segments)
|
59
|
-
File.join(::MerbAuth.dir_for(type), *segments)
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
3
|
-
<head>
|
4
|
-
<title>Auth::Slice Sample Layout</title>
|
5
|
-
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
6
|
-
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css">
|
7
|
-
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.1/build/base/base-min.css">
|
8
|
-
<link href="<%= public_path_for :stylesheet, 'master.css' %>" type="text/css" charset="utf-8" rel="stylesheet" media="all"/>
|
9
|
-
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
|
10
|
-
<script type="text/javascript">
|
11
|
-
(function($) {
|
12
|
-
$(document).ready(function() {
|
13
|
-
$(":text:visible:enabled:first").focus();
|
14
|
-
});
|
15
|
-
})(jQuery);
|
16
|
-
</script>
|
17
|
-
</head>
|
18
|
-
<body>
|
19
|
-
<div id="container">
|
20
|
-
<div id="header-container">
|
21
|
-
<span style="float:right;margin-right:50px">
|
22
|
-
<% if logged_in? %>
|
23
|
-
Welcome <%= current_user.name %>
|
24
|
-
| <a href="<%= url(:logout) %>">Sign out</a>
|
25
|
-
<% else %>
|
26
|
-
<a href="<%= url(:signup) %>">Join now</a>
|
27
|
-
| <a href="<%= url(:login) %>">Sign in</a>
|
28
|
-
<% end %>
|
29
|
-
</span>
|
30
|
-
<h1>Sample MerbAuth App</h1>
|
31
|
-
<hr />
|
32
|
-
</div>
|
33
|
-
|
34
|
-
<div id="main-container">
|
35
|
-
<%= catch_content :for_layout %>
|
36
|
-
</div>
|
37
|
-
|
38
|
-
<hr />
|
39
|
-
|
40
|
-
<div id="footer-container">
|
41
|
-
<div class="left"><%= __FILE__ %></div>
|
42
|
-
<div class="right">© 2008 PragmaQuest Inc. All rights reserved.</div>
|
43
|
-
</div>
|
44
|
-
</div>
|
45
|
-
</body>
|
46
|
-
</html>
|
47
|
-
|
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
<div>
|
3
|
-
<div class="form_description">
|
4
|
-
<h2>Member sign in</h2>
|
5
|
-
</div>
|
6
|
-
|
7
|
-
<form action="<%= url(:login) %>" method="post">
|
8
|
-
<% if request.post? -%>
|
9
|
-
<div class="error">
|
10
|
-
<h2>Incorrect username and password</h2>
|
11
|
-
</div>
|
12
|
-
<% end -%>
|
13
|
-
|
14
|
-
<p><label for="username">Username or e-mail</label>
|
15
|
-
<input type="text" name="username" value="<%= params[:username] %>"/></p>
|
16
|
-
|
17
|
-
<p><label for="password">Password</label>
|
18
|
-
<input type="password" name="password"/></p>
|
19
|
-
|
20
|
-
<p><input type="checkbox" name='remember_me' id='remember_me' value="1"/>
|
21
|
-
<label id='remember_me_lb' for="remember_me">Keep me signed in</label></p>
|
22
|
-
|
23
|
-
<p><input type="submit" value="Sign in"/> <span style="margin-left:20px"><a href="#">Forgot password?</a></span></p>
|
24
|
-
</form>
|
25
|
-
|
26
|
-
<form action="#" method="post" style="display:none">
|
27
|
-
<p><label for="openid_url">OpenID</label>
|
28
|
-
<input type="text" value="" size="40" id="openid_url" name="openid_url"/> <small>(e.g. http://username.myopenid.com)</small>
|
29
|
-
</p>
|
30
|
-
</form>
|
31
|
-
</div>
|
@@ -1,29 +0,0 @@
|
|
1
|
-
|
2
|
-
<div>
|
3
|
-
<div class="form_description">
|
4
|
-
<h2>Sign up here (it's absolutely free)</h2>
|
5
|
-
</div>
|
6
|
-
|
7
|
-
<% form_for @user, :action => url(:signup) do %>
|
8
|
-
<%= error_messages_for :user, lambda{|err| "<li>#{err.join('<br/>')}</li>"} %>
|
9
|
-
|
10
|
-
<p>
|
11
|
-
<%= text_control :name, :label => "Name" %>
|
12
|
-
</p>
|
13
|
-
<p>
|
14
|
-
<%= text_control :username, :label => "Username" %>
|
15
|
-
</p>
|
16
|
-
<p>
|
17
|
-
<%= text_control :email, :label => "E-mail" %>
|
18
|
-
</p>
|
19
|
-
<p>
|
20
|
-
<%= password_control :password, :label => "Password" %>
|
21
|
-
</p>
|
22
|
-
<p>
|
23
|
-
<%= password_control :password_confirmation, :label => "Password Confirmation" %>
|
24
|
-
</p>
|
25
|
-
<p>
|
26
|
-
<%= submit_button "Sign up" %> <span style="margin-left:20px">Already a member? <a href="<%= url(:login) %>">Sign in here</a></span>
|
27
|
-
</p>
|
28
|
-
<% end %>
|
29
|
-
</div>
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module MerbAuth
|
2
|
-
module Adapter
|
3
|
-
module Activerecord
|
4
|
-
def self.included(base)
|
5
|
-
base.class_eval do
|
6
|
-
include MerbAuth::BaseModel
|
7
|
-
extend ClassMethods
|
8
|
-
|
9
|
-
validates_presence_of :name
|
10
|
-
validates_presence_of :username
|
11
|
-
validates_presence_of :email
|
12
|
-
validates_length_of :username, :within => 3..40
|
13
|
-
validates_length_of :password, :within => 4..40, :if => :password_required?
|
14
|
-
validates_presence_of :password_confirmation, :if => :password_required?
|
15
|
-
validates_confirmation_of :password, :if => :password_required?
|
16
|
-
validates_uniqueness_of :username, :case_sensitive => false, :if => lambda { |u| !u.username.blank? }
|
17
|
-
validates_uniqueness_of :email, :case_sensitive => false, :if => lambda { |u| !u.email.blank? }
|
18
|
-
|
19
|
-
before_save :encrypt_password
|
20
|
-
|
21
|
-
def username=(value)
|
22
|
-
self[:username] = value.downcase if value
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
module ClassMethods
|
28
|
-
def drop_db_table
|
29
|
-
self.connection.drop_table("users")
|
30
|
-
end
|
31
|
-
|
32
|
-
def create_db_table
|
33
|
-
self.connection.create_table("users") do |t|
|
34
|
-
t.string :name, :limit => 40, :null => false
|
35
|
-
t.string :username, :limit => 40, :null => false
|
36
|
-
t.string :email, :null => false
|
37
|
-
t.string :crypted_password, :limit => 40
|
38
|
-
t.string :salt, :limit => 40, :null => false
|
39
|
-
t.string :remember_token
|
40
|
-
t.date :remember_token_expires_at
|
41
|
-
t.timestamps
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
MerbAuth.send(:remove_const, :User) if defined? MerbAuth::User
|
50
|
-
class MerbAuth::User < ActiveRecord::Base
|
51
|
-
include MerbAuth::Adapter::Activerecord
|
52
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'dm-core'
|
2
|
-
require 'dm-validations'
|
3
|
-
require 'dm-timestamps'
|
4
|
-
require 'dm-aggregates'
|
5
|
-
|
6
|
-
module MerbAuth
|
7
|
-
module Adapter
|
8
|
-
module Datamapper
|
9
|
-
def self.included(base)
|
10
|
-
base.class_eval do
|
11
|
-
include ::DataMapper::Resource
|
12
|
-
include MerbAuth::BaseModel
|
13
|
-
extend ClassMethods
|
14
|
-
|
15
|
-
storage_names[:default] = 'users'
|
16
|
-
|
17
|
-
property :id, Integer, :serial => true
|
18
|
-
property :name, String, :length => 3..40, :nullable => false
|
19
|
-
property :username, String, :length => 3..40, :nullable => false
|
20
|
-
property :email, String, :format => :email_address, :nullable => false
|
21
|
-
property :crypted_password, String, :length => 40
|
22
|
-
property :salt, String, :length => 40
|
23
|
-
property :remember_token_expires_at, Date
|
24
|
-
property :remember_token, String
|
25
|
-
property :created_at, DateTime
|
26
|
-
property :updated_at, DateTime
|
27
|
-
|
28
|
-
validates_is_unique :username, :email
|
29
|
-
validates_length :password, :in => 4..40, :if => :password_required?
|
30
|
-
validates_is_confirmed :password, :groups => :create
|
31
|
-
|
32
|
-
before :save, :encrypt_password
|
33
|
-
|
34
|
-
def username=(value)
|
35
|
-
attribute_set(:username, value.downcase) if value
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
module ClassMethods
|
41
|
-
def create_db_table
|
42
|
-
self.auto_migrate!
|
43
|
-
end
|
44
|
-
|
45
|
-
def drop_db_table
|
46
|
-
self.repository do |r|
|
47
|
-
r.adapter.destroy_model_storage(r, self)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def find_by_id(id)
|
52
|
-
MerbAuth::User.first(:id => id)
|
53
|
-
end
|
54
|
-
|
55
|
-
def find_by_remember_token(rt)
|
56
|
-
MerbAuth::User.first(:remember_token => rt)
|
57
|
-
end
|
58
|
-
|
59
|
-
def find_by_username(username)
|
60
|
-
if MerbAuth::User.properties[:activated_at]
|
61
|
-
MerbAuth::User.first(:username => username, :activated_at.not => nil)
|
62
|
-
else
|
63
|
-
MerbAuth::User.first(:username => username)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def find_by_activiation_code(activation_code)
|
68
|
-
MerbAuth::User.first(:activation_code => activation_code)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
MerbAuth.send(:remove_const, :User) if defined? MerbAuth::User
|
76
|
-
class MerbAuth::User
|
77
|
-
include MerbAuth::Adapter::Datamapper
|
78
|
-
end
|