sinatra-authentication-nedludd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ #sinatra_authentication
2
+ %h1.page_title
3
+ - if @user.email
4
+ = @user.email
5
+ - if current_user.admin?
6
+ %h2 permission level
7
+ = @user.permission_level
@@ -0,0 +1,21 @@
1
+ #sinatra_authentication
2
+ - if Rack.const_defined?('Flash')
3
+ #sinatra_authentication_flash= flash[:notice]
4
+ %h1.page_title Signup
5
+ %form{:action => "/signup", :method => "post"}
6
+ .field
7
+ .label
8
+ %label{:for => "user_email"} Email
9
+ %input{ :id => "user_email", :name => "user[email]", :size => 30, :type => "text" }
10
+ .field
11
+ .label
12
+ %label{:for => "user_password"} Password
13
+ %input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
14
+ .field
15
+ .label
16
+ %label{:for => "user_password_confirmation"} Confirm Password
17
+ %input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
18
+ .buttons
19
+ %input{ :value => "Create account", :type => "submit" }
20
+ %a{:href => "/login", :class => 'sinatra_authentication_link'}
21
+ Login
data/readme.markdown ADDED
@@ -0,0 +1,161 @@
1
+ ### A little sinatra gem that implements user authentication, with support for DataMapper.
2
+
3
+ (Forked from maxjustus' version. I don't need TC or Mongo, nor Facebook integration)
4
+
5
+ ## INSTALLATION:
6
+
7
+ In your sinatra app simply require "dm-core", "digest/sha1", 'rack-flash' (if you want flash messages) and then "sinatra-authentication" and turn on session storage with a super secret key, like so:
8
+
9
+ require "dm-core"
10
+ #for using auto_migrate!
11
+ require "dm-migrations"
12
+ require "digest/sha1"
13
+ require 'rack-flash'
14
+ require "sinatra-authentication"
15
+
16
+ use Rack::Session::Cookie, :secret => 'A1 sauce 1s so good you should use 1t on a11 yr st34ksssss'
17
+ #if you want flash messages
18
+ use Rack::Flash
19
+
20
+ ## DEFAULT ROUTES:
21
+
22
+ * get '/login'
23
+ * get '/logout'
24
+ * get '/signup'
25
+ * get/post '/users'
26
+ * get '/users/:id'
27
+ * get/post '/users/:id/edit'
28
+ * get '/users/:id/delete'
29
+
30
+ If you fetch any of the user pages using ajax, they will automatically render without a layout
31
+
32
+ ## FLASH MESSAGES
33
+
34
+ Flash messages are implemented using rack-flash. To set them up add this to your code:
35
+
36
+ require 'rack-flash'
37
+
38
+ #be sure and do this after after 'use Rack:Session:Cookie...'
39
+ use Rack::Flash
40
+
41
+ And then sinatra-authentication related flash messages will be made available through flash[:notice]
42
+
43
+ -# somewhere in a haml view:
44
+ = flash[:notice]
45
+
46
+ ## HELPER METHODS:
47
+
48
+ This plugin provides the following helper methods for your sinatra app:
49
+
50
+ * login_required
51
+ > which you place at the beginning of any routes you want to be protected
52
+ * current_user
53
+ * logged_in?
54
+ * render_login_logout(html_attributes)
55
+ > Which renders login/logout and singup/edit account links.
56
+ If you pass a hash of html parameters to render_login_logout all the links will get set to them.
57
+ Which is useful for if you're using some sort of lightbox
58
+
59
+ ## SIMPLE PERMISSIONS:
60
+
61
+ By default the user class includes a method called admin? which simply checks
62
+ if user.permission_level == -1.
63
+
64
+ you can take advantage of this method in your views or controllers by calling
65
+ current_user.admin?
66
+ i.e.
67
+
68
+ - if current_user.admin?
69
+ %a{:href => "/adminey_link_route_thing"} do something adminey
70
+
71
+ (these view examples are in HAML, by the way)
72
+
73
+ You can also extend the user class with any convenience methods for determining permissions.
74
+ i.e.
75
+
76
+ #somewhere in the murky depths of your sinatra app
77
+ class User
78
+ def peasant?
79
+ self.permission_level == 0
80
+ end
81
+ end
82
+
83
+ then in your views you can do
84
+
85
+ - if current_user.peasant?
86
+ %h1 hello peasant!
87
+ %p Welcome to the caste system! It's very depressing.
88
+
89
+ if no one is logged in, current_user returns a GuestUser instance, which responds to current_user.guest?
90
+ with true, current_user.permission_level with 0 and any other method calls with false
91
+
92
+ This makes some view logic easier since you don't always have to check if the user is logged in,
93
+ although a logged_in? helper method is still provided
94
+
95
+
96
+ ## OVERRIDING DEFAULT VIEWS
97
+
98
+ Right now if you're going to override sinatra-authentication's views, you have to override all of them.
99
+ This is something I hope to change in a future release.
100
+
101
+ To override the default view path do something like this:
102
+
103
+ set :sinatra_authentication_view_path, Pathname(__FILE__).dirname.expand_path + "my_views/"
104
+
105
+ And then the views you'll need to define are:
106
+
107
+ * show.haml
108
+ * index.haml
109
+ * signup.haml
110
+ * login.haml
111
+ * edit.haml
112
+
113
+ The signup and edit form fields are named so they pass a hash called 'user' to the server:
114
+
115
+ %input{:name => "user[email]", :size => 30, :type => "text", :value => @user.email}
116
+ %input{:name => "user[password]", :size => 30, :type => "password"}
117
+ %input{:name => "user[password_confirmation]", :size => 30, :type => "password"}
118
+
119
+ %select{:name => "user[permission_level]"}
120
+ %option{:value => -1, :selected => @user.admin?}
121
+ Admin
122
+ %option{:value => 1, :selected => @user.permission_level == 1}
123
+ Authenticated user
124
+
125
+ if you add attributes to the User class and pass them in the user hash your new attributes will be set along with the others.
126
+
127
+ The login form fields just pass a field called email and a field called password:
128
+
129
+ %input{:name => "email", :size => 30, :type => "text"}
130
+ %input{:name => "password", :size => 30, :type => "password"}
131
+
132
+ To add methods or properties to the User class, you have to access the underlying database user class, like so:
133
+
134
+ class DmUser
135
+ property :name, String
136
+ property :has_dog, Boolean, :default => false
137
+ end
138
+
139
+ And then to access/update your newly defined attributes you use the User class:
140
+
141
+ current_user.name
142
+ current_user.has_dog
143
+
144
+ current_user.update({:has_dog => true})
145
+
146
+ new_user = User.set({:email => 'max@max.com' :password => 'hi', :password_confirmation => 'hi', :name => 'Max', :has_dog => false})
147
+
148
+ User.all(:has_dog => true).each do |user|
149
+ user.update({has_dog => false})
150
+ end
151
+
152
+ User.all(:has_dog => false).each do |user|
153
+ user.delete
154
+ end
155
+
156
+ the User class passes additional method calls along to the interfacing database class, so calls to Datamapper functions should work as expected.
157
+
158
+ The database user class is named
159
+
160
+ DmUser
161
+
@@ -0,0 +1,97 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sinatra-authentication-nedludd}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Max Justus Spransy" "Tim Hermans"]
12
+ s.date = %q{2010-06-29}
13
+ s.description = %q{Simple authentication plugin for sinatra.}
14
+ s.email = ["maxjustus@gmail.com" "thermans@gmail.com"]
15
+ s.extra_rdoc_files = [
16
+ "TODO"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "History.txt",
21
+ "Manifest",
22
+ "Rakefile",
23
+ "TODO",
24
+ "example/dm_extend_app.rb",
25
+ "example/dm_sinbook.rb",
26
+ "example/extend_views/edit.haml",
27
+ "example/extend_views/index.haml",
28
+ "example/extend_views/login.haml",
29
+ "example/extend_views/show.haml",
30
+ "example/extend_views/signup.haml",
31
+ "example/mm_app.rb",
32
+ "example/tc_app.rb",
33
+ "example/tc_sinbook.rb",
34
+ "lib/models/abstract_user.rb",
35
+ "lib/models/datamapper_user.rb",
36
+ "lib/models/dm_adapter.rb",
37
+ "lib/sinatra-authentication.rb",
38
+ "lib/views/edit.haml",
39
+ "lib/views/index.haml",
40
+ "lib/views/login.haml",
41
+ "lib/views/show.haml",
42
+ "lib/views/signup.haml",
43
+ "readme.markdown",
44
+ "sinatra-authentication-nedludd.gemspec",
45
+ "test/datamapper_test.rb",
46
+ "test/lib/dm_app.rb",
47
+ "test/lib/dm_extend_app.rb",
48
+ "test/lib/extend_views/edit.haml",
49
+ "test/lib/extend_views/index.haml",
50
+ "test/lib/extend_views/login.haml",
51
+ "test/lib/extend_views/show.haml",
52
+ "test/lib/extend_views/signup.haml",
53
+ "test/lib/helper.rb",
54
+ "test/route_tests.rb"
55
+ ]
56
+ s.homepage = %q{http://github.com/nedludd/sinatra-authentication}
57
+ s.rdoc_options = ["--charset=UTF-8"]
58
+ s.require_paths = ["lib"]
59
+ s.rubygems_version = %q{1.3.7}
60
+ s.summary = %q{Simple authentication plugin for sinatra.}
61
+ s.test_files = [
62
+ "test/route_tests.rb",
63
+ "test/datamapper_test.rb",
64
+ "test/lib/dm_app.rb",
65
+ "test/lib/helper.rb",
66
+ "test/lib/dm_extend_app.rb"
67
+ ]
68
+
69
+ if s.respond_to? :specification_version then
70
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
71
+ s.specification_version = 3
72
+
73
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
74
+ s.add_runtime_dependency(%q<sinatra>, [">= 0"])
75
+ s.add_runtime_dependency(%q<dm-core>, [">= 0"])
76
+ s.add_runtime_dependency(%q<dm-migrations>, [">= 0"])
77
+ s.add_runtime_dependency(%q<dm-validations>, [">= 0"])
78
+ s.add_runtime_dependency(%q<dm-timestamps>, [">= 0"])
79
+ s.add_runtime_dependency(%q<rack-flash>, [">= 0"])
80
+ else
81
+ s.add_dependency(%q<sinatra>, [">= 0"])
82
+ s.add_dependency(%q<dm-core>, [">= 0"])
83
+ s.add_dependency(%q<dm-migrations>, [">= 0"])
84
+ s.add_dependency(%q<dm-validations>, [">= 0"])
85
+ s.add_dependency(%q<dm-timestamps>, [">= 0"])
86
+ s.add_dependency(%q<rack-flash>, [">= 0"])
87
+ end
88
+ else
89
+ s.add_dependency(%q<sinatra>, [">= 0"])
90
+ s.add_dependency(%q<dm-core>, [">= 0"])
91
+ s.add_dependency(%q<dm-migrations>, [">= 0"])
92
+ s.add_dependency(%q<dm-validations>, [">= 0"])
93
+ s.add_dependency(%q<dm-timestamps>, [">= 0"])
94
+ s.add_dependency(%q<rack-flash>, [">= 0"])
95
+ end
96
+ end
97
+
@@ -0,0 +1,5 @@
1
+ require 'lib/dm_app'
2
+ require 'lib/helper'
3
+ require 'test/unit'
4
+ require 'rack/test'
5
+ require 'route_tests'
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'haml'
4
+ require 'dm-core'
5
+ require 'rack-flash'
6
+ require File.join(File.dirname(__FILE__), '../../lib/sinatra-authentication')
7
+
8
+ DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/test.db")
9
+ DataMapper.auto_migrate!
10
+
11
+ use Rack::Session::Cookie, :secret => "heyhihello"
12
+ use Rack::Flash
13
+
14
+ set :environment, 'development'
15
+ set :public, 'public'
16
+ set :views, 'views'
17
+
18
+ get '/' do
19
+ haml "= render_login_logout", :layout => :layout
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+ require 'haml'
4
+ require 'dm-core'
5
+ require 'rack-flash'
6
+ require File.join(File.dirname(__FILE__), '../../lib/sinatra-authentication')
7
+
8
+
9
+ class DmUser
10
+ property :name, String
11
+ end
12
+
13
+ DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/test.db")
14
+ DataMapper.auto_migrate!
15
+
16
+ set :sinatra_authentication_view_path, Pathname(__FILE__).dirname.expand_path + "extend_views/"
17
+ use Rack::Session::Cookie, :secret => "heyhihello"
18
+ use Rack::Flash
19
+
20
+ set :environment, 'development'
21
+ set :public, 'public'
22
+ set :views, 'views'
23
+
24
+ get '/' do
25
+ puts User.all(:name => 'max')
26
+ haml "= render_login_logout", :layout => :layout
27
+ end
@@ -0,0 +1,42 @@
1
+ #sinatra_authentication
2
+ #sinatra_authentication_flash= session[:flash]
3
+ %h1
4
+ Edit
5
+ - if @user.id == current_user.id
6
+ account
7
+ - else
8
+ - if @user.email
9
+ = @user.email
10
+ - elsif @user.fb_uid
11
+ <fb:name uid=#{@user.fb_uid} linked='false' />
12
+ - else
13
+ account
14
+ %form{:action => "/users/#{@user.id}/edit", :method => "post"}
15
+ .field
16
+ .label
17
+ %label{:for => "user_email"} Email
18
+ %input{ :id => "user_email", :name => "user[email]", :size => 30, :type => "text", :value => @user.email }
19
+ .field
20
+ .label
21
+ %label{:for => "user_password"} New password
22
+ %input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
23
+ .field
24
+ .label
25
+ %label{:for => "user_password_confirmation"} Confirm
26
+ %input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
27
+ -# don't render permission field if admin and editing yourself so you don't shoot yourself in the foot
28
+ - if current_user.admin? && current_user.id != @user.id
29
+ .field
30
+ .label
31
+ %label{:for => 'permission_level'} Permission level
32
+ %select{ :id => "permission_level", :name => "user[permission_level]" }
33
+ %option{:value => -1, :selected => @user.admin?}
34
+ Admin
35
+ %option{:value => 1, :selected => @user.permission_level == 1}
36
+ Authenticated user
37
+ .buttons
38
+ %input{ :value => "Update", :type => "submit" }
39
+ - if Sinatra.const_defined?('FacebookObject')
40
+ - unless @user.fb_uid
41
+ |
42
+ = render_facebook_connect_link('Link account with Facebook')
@@ -0,0 +1,31 @@
1
+ #sinatra_authentication
2
+ %h1.page_title Users
3
+ %table
4
+ %tr
5
+ %th
6
+ - if current_user.admin?
7
+ %th permission level
8
+ - @users.each do |user|
9
+ %tr
10
+ %td
11
+ - if user.email
12
+ = user.email
13
+ - elsif user.fb_uid
14
+ <fb:name uid=#{user.fb_uid} />
15
+ - else
16
+ "user #{user.id}"
17
+ - if current_user.admin?
18
+ %td= user.permission_level
19
+ %td
20
+ = user.name
21
+ %td
22
+ %a{:href => "/users/#{user.id}"} show
23
+ - if current_user.admin?
24
+ %td
25
+ %a{:href => "/users/#{user.id}/edit"} edit
26
+ %td
27
+ -# this doesn't work for tk
28
+ - if !user.site_admin?
29
+ %a{:href => "/users/#{user.id}/delete", :onclick => "return confirm('you sure?')"} delete
30
+ - else
31
+ site admin
@@ -0,0 +1,21 @@
1
+ #sinatra_authentication
2
+ #sinatra_authentication_flash= session[:flash]
3
+ %h1.page_title Login
4
+ %form{:action => "/login", :method => "post"}
5
+ .field
6
+ .label
7
+ %label{:for => "user_email'"} Email
8
+ %input{:id => "user_email", :name => "email", :size => 30, :type => "text"}
9
+ .field
10
+ .label
11
+ %label{:for => "user_password"} Password
12
+ %input{:id => "user_password", :name => "password", :size => 30, :type => "password"}
13
+ .buttons
14
+ %input{:value => "login", :type => "submit"}
15
+ %a{:href => "/signup", :class => 'sinatra_authentication_link'}
16
+ Signup
17
+ - if Sinatra.const_defined?('FacebookObject')
18
+ .third_party_signup
19
+ %h3.section_title One click login:
20
+ .login_link.facebook_login
21
+ = render_facebook_connect_link('Login using facebook', :size => 'large')