maxjustus-sinatra-authentication 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest +12 -0
- data/Rakefile +15 -0
- data/TODO +11 -0
- data/lib/models/user.rb +50 -0
- data/lib/sinatra-authentication.rb +210 -0
- data/lib/views/edit.haml +21 -0
- data/lib/views/index.haml +19 -0
- data/lib/views/login.haml +10 -0
- data/lib/views/show.haml +5 -0
- data/lib/views/signup.haml +13 -0
- data/readme.rdoc +71 -0
- data/sinatra-authentication.gemspec +43 -0
- metadata +116 -0
data/History.txt
ADDED
data/Manifest
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('sinatra-authentication', '0.0.1') do |p|
|
6
|
+
p.description = "Simple authentication plugin for sinatra."
|
7
|
+
p.url = "http://github.com/maxjustus/sinatra-authentication"
|
8
|
+
p.author = "Max Justus Spransy"
|
9
|
+
p.email = "maxjustus@gmail.com"
|
10
|
+
p.ignore_pattern = []
|
11
|
+
p.development_dependencies = ["sinatra", "dm-core", "dm-timestamps", "dm-validations"]
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/TODO
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
TODO:
|
2
|
+
- write rake task which creates first admin user
|
3
|
+
after writing this, change the User.permission_level default value to 0
|
4
|
+
|
5
|
+
implement some way to allow for the creation of users with different
|
6
|
+
permission levels in an untamperable manner. Perhaps with some secret key
|
7
|
+
that must be sent in the form
|
8
|
+
- look at other permissions systems for some feature ideas
|
9
|
+
- ?implement a session store which isn't cookie based
|
10
|
+
- turn on sessions unless they're already on
|
11
|
+
- randomize the session key on every installation
|
data/lib/models/user.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
class User
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
attr_accessor :password, :password_confirmation
|
5
|
+
|
6
|
+
property :id, Serial, :protected => true
|
7
|
+
property :email, String, :key => true, :nullable => false, :length => (5..40), :unique => true, :format => :email_address
|
8
|
+
property :hashed_password, String
|
9
|
+
property :salt, String, :protected => true, :nullable => false
|
10
|
+
property :created_at, DateTime
|
11
|
+
property :permission_level, Integer, :default => -1
|
12
|
+
|
13
|
+
validates_present :password_confirmation, :unless => Proc.new { |t| t.hashed_password }
|
14
|
+
validates_present :password, :unless => Proc.new { |t| t.hashed_password }
|
15
|
+
validates_is_confirmed :password
|
16
|
+
|
17
|
+
def self.authenticate(email, pass)
|
18
|
+
current_user = first(:email => email)
|
19
|
+
return nil if current_user.nil?
|
20
|
+
return current_user if User.encrypt(pass, current_user.salt) == current_user.hashed_password
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def password=(pass)
|
25
|
+
@password = pass
|
26
|
+
self.salt = User.random_string(10) if !self.salt
|
27
|
+
self.hashed_password = User.encrypt(@password, self.salt)
|
28
|
+
end
|
29
|
+
|
30
|
+
def admin?
|
31
|
+
self.permission_level == -1
|
32
|
+
end
|
33
|
+
protected
|
34
|
+
|
35
|
+
def self.encrypt(pass, salt)
|
36
|
+
Digest::SHA1.hexdigest(pass+salt)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.random_string(len)
|
40
|
+
#generate a random password consisting of strings and digits
|
41
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
42
|
+
newpass = ""
|
43
|
+
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
|
44
|
+
return newpass
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(m, *args)
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'dm-core'
|
3
|
+
require 'dm-timestamps'
|
4
|
+
require 'dm-validations'
|
5
|
+
require Pathname(__FILE__).dirname.expand_path + "models/user"
|
6
|
+
|
7
|
+
module SinatraAuthentication
|
8
|
+
VERSION = "0.0.1"
|
9
|
+
end
|
10
|
+
|
11
|
+
module Sinatra
|
12
|
+
module LilAuthentication
|
13
|
+
def self.registered(app)
|
14
|
+
#INVESTIGATE
|
15
|
+
#the possibility of sinatra having an array of view_paths to load from
|
16
|
+
#PROBLEM
|
17
|
+
#sinatra 9.1.1 doesn't have multiple view capability anywhere
|
18
|
+
#so to get around I have to do it totally manually by
|
19
|
+
#loading the view from this path into a string and rendering it
|
20
|
+
set :lil_authentication_view_path, Pathname(__FILE__).dirname.expand_path + "views/"
|
21
|
+
|
22
|
+
#TODO write captain sinatra developer man and inform him that the documentation
|
23
|
+
#conserning the writing of extensions is somewhat outdaded/incorrect.
|
24
|
+
#you do not need to to do self.get/self.post when writing an extension
|
25
|
+
#In fact, it doesn't work. You have to use the plain old sinatra DSL
|
26
|
+
|
27
|
+
get '/users' do
|
28
|
+
@users = User.all
|
29
|
+
if @users != []
|
30
|
+
haml get_view_as_string("index.haml"), :layout => use_layout?
|
31
|
+
else
|
32
|
+
redirect '/signup'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
get '/users/:id' do
|
37
|
+
login_required
|
38
|
+
|
39
|
+
#INVESTIGATE
|
40
|
+
#
|
41
|
+
#WHY THE HECK WON'T GET RETURN ANYTHING?
|
42
|
+
#if I user User.get(params[:id]) it returns nil for some inexplicable reason
|
43
|
+
@user = User.first(:id => params[:id])
|
44
|
+
haml get_view_as_string("show.haml"), :layout => use_layout?
|
45
|
+
end
|
46
|
+
|
47
|
+
#convenience for ajax but maybe entirely stupid and unnecesary
|
48
|
+
get '/logged_in' do
|
49
|
+
if session[:user]
|
50
|
+
"true"
|
51
|
+
else
|
52
|
+
"false"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
get '/login' do
|
57
|
+
haml get_view_as_string("login.haml"), :layout => use_layout?
|
58
|
+
end
|
59
|
+
|
60
|
+
post '/login' do
|
61
|
+
if user = User.authenticate(params[:email], params[:password])
|
62
|
+
session[:user] = user.id
|
63
|
+
redirect '/'
|
64
|
+
else
|
65
|
+
redirect '/login'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
get '/logout' do
|
70
|
+
session[:user] = nil
|
71
|
+
@message = "in case it weren't obvious, you've logged out"
|
72
|
+
redirect '/'
|
73
|
+
end
|
74
|
+
|
75
|
+
get '/signup' do
|
76
|
+
haml get_view_as_string("signup.haml"), :layout => use_layout?
|
77
|
+
end
|
78
|
+
|
79
|
+
post '/signup' do
|
80
|
+
@user = User.new(params[:user])
|
81
|
+
if @user.save
|
82
|
+
session[:user] = @user.id
|
83
|
+
redirect '/'
|
84
|
+
else
|
85
|
+
session[:flash] = "failure!"
|
86
|
+
redirect '/'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
get '/users/:id/edit' do
|
91
|
+
login_required
|
92
|
+
redirect "/users" unless current_user.admin? || current_user == params[:id]
|
93
|
+
|
94
|
+
@user = User.first(:id => params[:id])
|
95
|
+
haml get_view_as_string("edit.haml"), :layout => use_layout?
|
96
|
+
end
|
97
|
+
|
98
|
+
post '/users/:id/edit' do
|
99
|
+
login_required
|
100
|
+
redirect "/users" unless current_user.admin? || current_user == params[:id]
|
101
|
+
|
102
|
+
user = User.first(:id => params[:id])
|
103
|
+
user_attributes = params[:user]
|
104
|
+
if params[:user][:password] == ""
|
105
|
+
user_attributes.delete("password")
|
106
|
+
user_attributes.delete("password_confirmation")
|
107
|
+
end
|
108
|
+
|
109
|
+
if user.update_attributes(user_attributes)
|
110
|
+
redirect "/users/#{user.id}"
|
111
|
+
else
|
112
|
+
throw user.errors
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
get '/users/:id/delete' do
|
117
|
+
login_required
|
118
|
+
redirect "/users" unless current_user.admin? || current_user == params[:id]
|
119
|
+
|
120
|
+
user = User.first(:id => params[:id])
|
121
|
+
user.destroy
|
122
|
+
session[:flash] = "way to go, you deleted a user"
|
123
|
+
redirect '/'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
module Helpers
|
131
|
+
def login_required
|
132
|
+
if session[:user]
|
133
|
+
return true
|
134
|
+
else
|
135
|
+
session[:return_to] = request.fullpath
|
136
|
+
redirect '/login'
|
137
|
+
return false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def current_user
|
142
|
+
# TODO
|
143
|
+
# considering returning a user like object with a permission method if not logged in
|
144
|
+
if session[:user]
|
145
|
+
User.first(:id => session[:user])
|
146
|
+
else
|
147
|
+
GuestUser.new
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def logged_in?
|
152
|
+
!!session[:user]
|
153
|
+
end
|
154
|
+
|
155
|
+
def use_layout?
|
156
|
+
!request.xhr?
|
157
|
+
end
|
158
|
+
|
159
|
+
#BECAUSE sinatra 9.1.1 can't load views from different paths properly
|
160
|
+
def get_view_as_string(filename)
|
161
|
+
view = options.lil_authentication_view_path + filename
|
162
|
+
data = ""
|
163
|
+
f = File.open(view, "r")
|
164
|
+
f.each_line do |line|
|
165
|
+
data += line
|
166
|
+
end
|
167
|
+
return data
|
168
|
+
end
|
169
|
+
|
170
|
+
def render_login_logout(html_attributes = {:class => ""})
|
171
|
+
css_classes = html_attributes.delete(:class)
|
172
|
+
parameters = ''
|
173
|
+
html_attributes.each_pair do |attribute, value|
|
174
|
+
parameters += "#{attribute}=\"#{value}\" "
|
175
|
+
end
|
176
|
+
|
177
|
+
result = "<div id='sinatra-authentication-login-logout' >"
|
178
|
+
if logged_in?
|
179
|
+
logout_parameters = html_attributes
|
180
|
+
# a tad janky?
|
181
|
+
logout_parameters.delete(:rel)
|
182
|
+
result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>logout</a> "
|
183
|
+
result += "<a href='/users/#{current_user.id}/edit' class='#{css_classes} sinatra-authentication-edit' #{parameters}>edit account</a>"
|
184
|
+
else
|
185
|
+
result += "<a href='/login' class='#{css_classes} sinatra-authentication-login' #{parameters}>login</a> "
|
186
|
+
result += "<a href='/signup' class='#{css_classes} sinatra-authentication-signup' #{parameters}>signup</a>"
|
187
|
+
end
|
188
|
+
|
189
|
+
result += "</div>"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
register LilAuthentication
|
194
|
+
end
|
195
|
+
|
196
|
+
class GuestUser
|
197
|
+
def guest?
|
198
|
+
true
|
199
|
+
end
|
200
|
+
|
201
|
+
def permission_level
|
202
|
+
0
|
203
|
+
end
|
204
|
+
|
205
|
+
# current_user.admin? returns false. current_user.has_a_baby? returns false.
|
206
|
+
# (which is a bit of an assumption I suppose)
|
207
|
+
def method_missing(m, *args)
|
208
|
+
return false
|
209
|
+
end
|
210
|
+
end
|
data/lib/views/edit.haml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#sinatra_authentication
|
2
|
+
%h1
|
3
|
+
Editing
|
4
|
+
= @user.email
|
5
|
+
%form{:action => "/users/#{@user.id}/edit", :method => "post"}
|
6
|
+
%input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
|
7
|
+
new password
|
8
|
+
%br
|
9
|
+
%input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
|
10
|
+
confirm
|
11
|
+
-# don't render permission field if admin and editing yourself so you don't shoot yourself in the foot
|
12
|
+
- if current_user.admin? && current_user.id != @user.id
|
13
|
+
%br
|
14
|
+
%select{ :id => "permission_level", :name => "user[permission_level]" }
|
15
|
+
%option{:value => -1}
|
16
|
+
admin
|
17
|
+
%option{:value => 1}
|
18
|
+
authenticated user
|
19
|
+
permission level
|
20
|
+
%br
|
21
|
+
%input{ :value => "update", :type => "submit" }
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#sinatra_authentication
|
2
|
+
%h1 Users
|
3
|
+
%table
|
4
|
+
%tr
|
5
|
+
%th email
|
6
|
+
- if current_user.admin?
|
7
|
+
%th permission level
|
8
|
+
- @users.each do |user|
|
9
|
+
%tr
|
10
|
+
%td= user.email
|
11
|
+
- if current_user.admin?
|
12
|
+
%td= user.permission_level
|
13
|
+
%td
|
14
|
+
%a{:href => "/users/#{user.id}"} show
|
15
|
+
- if current_user.admin?
|
16
|
+
%td
|
17
|
+
%a{:href => "/users/#{user.id}/edit"} edit
|
18
|
+
%td
|
19
|
+
%a{:href => "/users/#{user.id}/delete", :onclick => "return confirm('you sure?')"} delete
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#sinatra_authentication
|
2
|
+
%h1 Login
|
3
|
+
%form{:action => "/login", :method => "post"}
|
4
|
+
%input{:id => "user_email", :name => "email", :size => 30, :type => "text"}
|
5
|
+
email
|
6
|
+
%br
|
7
|
+
%input{:id => "user_password", :name => "password", :size => 30, :type => "password"}
|
8
|
+
password
|
9
|
+
%br
|
10
|
+
%input{:value => "login", :type => "submit"}
|
data/lib/views/show.haml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#sinatra_authentication
|
2
|
+
%h1 Signup
|
3
|
+
%form{:action => "/signup", :method => "post"}
|
4
|
+
%input{ :id => "user_email", :name => "user[email]", :size => 30, :type => "text" }
|
5
|
+
email
|
6
|
+
%br
|
7
|
+
%input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
|
8
|
+
password
|
9
|
+
%br
|
10
|
+
%input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
|
11
|
+
confirm
|
12
|
+
%br
|
13
|
+
%input{ :value => "sign up", :type => "submit" }
|
data/readme.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
a little sinatra gem that implements user authentication
|
2
|
+
|
3
|
+
INSTALLATION:
|
4
|
+
|
5
|
+
in your sinatra app simply include "sinatra-authentication" and turn on session storage
|
6
|
+
with a super secret key, like so:
|
7
|
+
|
8
|
+
include "sinatra-authentication"
|
9
|
+
|
10
|
+
use Rack::Session::Cookie, :secret => 'A1 sauce 1s so good you should use 1t on a11 yr st34ksssss'
|
11
|
+
|
12
|
+
DEFAULT ROUTES
|
13
|
+
|
14
|
+
- get '/login'
|
15
|
+
- get '/logout'
|
16
|
+
- get '/signup'
|
17
|
+
- get/post '/users'
|
18
|
+
- get '/users/:id'
|
19
|
+
- get/post '/users/:id/edit'
|
20
|
+
- get '/users/:id/delete'
|
21
|
+
|
22
|
+
If you fetch any of the user pages using ajax, they will automatically render without a layout
|
23
|
+
|
24
|
+
HELPER METHODS
|
25
|
+
|
26
|
+
This plugin provides the following helper methods for your sinatra app:
|
27
|
+
|
28
|
+
- login_required
|
29
|
+
which you place at the beginning of any routes you want to be protected
|
30
|
+
- current_user
|
31
|
+
- logged_in?
|
32
|
+
- render_login_logout(html_attributes)
|
33
|
+
Which renders login/logout and singup/edit account links.
|
34
|
+
If you pass a hash of html parameters to render_login_logout all the links will get set to them.
|
35
|
+
Which useful for if you're using some sort of lightbox
|
36
|
+
|
37
|
+
SIMPLE PERMISSIONS
|
38
|
+
|
39
|
+
By default the user class includes a method called admin? which simply checks
|
40
|
+
if user.permission_level == -1.
|
41
|
+
|
42
|
+
you can take advantage of this method in your views or controllers by calling
|
43
|
+
current_user.admin?
|
44
|
+
i.e.
|
45
|
+
|
46
|
+
- if current_user.admin?
|
47
|
+
%a{:href => "/adminey_link_route_thing"} do something adminey
|
48
|
+
|
49
|
+
(these view examples are in HAML, by the way)
|
50
|
+
|
51
|
+
You can also extend the user class with any convenience methods for determining permissions.
|
52
|
+
i.e.
|
53
|
+
|
54
|
+
#somewhere in the murky depths of your sinatra app
|
55
|
+
class User
|
56
|
+
def peasant?
|
57
|
+
self.permission_level == 0
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
then in your views you can do
|
62
|
+
|
63
|
+
- if current_user.peasant?
|
64
|
+
%h1 hello peasant!
|
65
|
+
%p Welcome to the caste system! It's very depressing.
|
66
|
+
|
67
|
+
if no one is logged in, current_user returns a GuestUser instance, which responds to current_user.guest?
|
68
|
+
with true, current_user.permission_level with 0 and any other method calls with false
|
69
|
+
|
70
|
+
This makes some view logic easier since you don't always have to check if the user is logged in,
|
71
|
+
although a logged_in? helper method is still provided
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{sinatra-authentication}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Max Justus Spransy"]
|
9
|
+
s.date = %q{2009-04-21}
|
10
|
+
s.description = %q{Simple authentication plugin for sinatra.}
|
11
|
+
s.email = %q{maxjustus@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["lib/models/user.rb", "lib/views/signup.haml", "lib/views/edit.haml", "lib/views/login.haml", "lib/views/index.haml", "lib/views/show.haml", "lib/sinatra-authentication.rb", "TODO"]
|
13
|
+
s.files = ["lib/models/user.rb", "lib/views/signup.haml", "lib/views/edit.haml", "lib/views/login.haml", "lib/views/index.haml", "lib/views/show.haml", "lib/sinatra-authentication.rb", "History.txt", "Rakefile", "readme.rdoc", "TODO", "Manifest", "sinatra-authentication.gemspec"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/maxjustus/sinatra-authentication}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sinatra-authentication", "--main", "readme.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{sinatra-authentication}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{Simple authentication plugin for sinatra.}
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 2
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_development_dependency(%q<sinatra>, [">= 0"])
|
28
|
+
s.add_development_dependency(%q<dm-core>, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<dm-timestamps>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<dm-validations>, [">= 0"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
33
|
+
s.add_dependency(%q<dm-core>, [">= 0"])
|
34
|
+
s.add_dependency(%q<dm-timestamps>, [">= 0"])
|
35
|
+
s.add_dependency(%q<dm-validations>, [">= 0"])
|
36
|
+
end
|
37
|
+
else
|
38
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
39
|
+
s.add_dependency(%q<dm-core>, [">= 0"])
|
40
|
+
s.add_dependency(%q<dm-timestamps>, [">= 0"])
|
41
|
+
s.add_dependency(%q<dm-validations>, [">= 0"])
|
42
|
+
end
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maxjustus-sinatra-authentication
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Max Justus Spransy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-21 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sinatra
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: dm-core
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: dm-timestamps
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: dm-validations
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
description: Simple authentication plugin for sinatra.
|
56
|
+
email: maxjustus@gmail.com
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- lib/models/user.rb
|
63
|
+
- lib/views/signup.haml
|
64
|
+
- lib/views/edit.haml
|
65
|
+
- lib/views/login.haml
|
66
|
+
- lib/views/index.haml
|
67
|
+
- lib/views/show.haml
|
68
|
+
- lib/sinatra-authentication.rb
|
69
|
+
- TODO
|
70
|
+
files:
|
71
|
+
- lib/models/user.rb
|
72
|
+
- lib/views/signup.haml
|
73
|
+
- lib/views/edit.haml
|
74
|
+
- lib/views/login.haml
|
75
|
+
- lib/views/index.haml
|
76
|
+
- lib/views/show.haml
|
77
|
+
- lib/sinatra-authentication.rb
|
78
|
+
- History.txt
|
79
|
+
- Rakefile
|
80
|
+
- readme.rdoc
|
81
|
+
- TODO
|
82
|
+
- Manifest
|
83
|
+
- sinatra-authentication.gemspec
|
84
|
+
has_rdoc: true
|
85
|
+
homepage: http://github.com/maxjustus/sinatra-authentication
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options:
|
88
|
+
- --line-numbers
|
89
|
+
- --inline-source
|
90
|
+
- --title
|
91
|
+
- Sinatra-authentication
|
92
|
+
- --main
|
93
|
+
- readme.rdoc
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: "0"
|
101
|
+
version:
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: "1.2"
|
107
|
+
version:
|
108
|
+
requirements: []
|
109
|
+
|
110
|
+
rubyforge_project: sinatra-authentication
|
111
|
+
rubygems_version: 1.2.0
|
112
|
+
signing_key:
|
113
|
+
specification_version: 2
|
114
|
+
summary: Simple authentication plugin for sinatra.
|
115
|
+
test_files: []
|
116
|
+
|