accounts 0.0.1

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.
@@ -0,0 +1,21 @@
1
+ !!!
2
+ %html{html_attrs}
3
+ / Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
4
+
5
+ %body.forgot_password
6
+
7
+ %h1 Forgot my password
8
+
9
+ %form.forgot_password(action="/forgot-password" method="POST")
10
+ .label_input
11
+ %label{:for=>"email"} E-mail
12
+ %input{:name=>"email", :id=>"email", :type=>"text"}
13
+ .button
14
+ %button{:type => "submit", } Submit
15
+
16
+ %p
17
+ We will send an e-mail to you with a one-time link that will
18
+ take you to a page that will allow you to change your password.
19
+
20
+ %p
21
+ Meanwhile, if you remember your password, it will still work until you change it.
@@ -0,0 +1,24 @@
1
+ !!!
2
+
3
+ %html{html_attrs}
4
+ / Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
5
+
6
+ %body
7
+
8
+ %h1 Sign in
9
+
10
+ %form#login_form(action="logon" method="POST")
11
+ .label_input
12
+ %label{:for=>"email"} E-mail
13
+ %input{:name=>"email", :id=>"email", :type=>"text", :value=>@email}
14
+ .label_input
15
+ %label{:for=>"password"} Password
16
+ %input{:name=>"password", :id=>"password", :type=>"password"}
17
+ .button
18
+ %button{:type => "submit"} Submit
19
+
20
+ .reset_password
21
+ %a{:href=>"/forgot-password"} I forgot my password.
22
+
23
+ .register
24
+ %a{:href=>"/register"} Register!
@@ -0,0 +1,15 @@
1
+ !!!
2
+
3
+ %html{html_attrs}
4
+ / Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
5
+
6
+ %body
7
+
8
+ %h1 Register
9
+
10
+ %form#login_form{:action => '/register', :method => 'post'}
11
+ .label_input
12
+ %label{:for=>"email"} E-mail
13
+ %input{:name=>"email", :id=>"email", :type=>"text"}
14
+ .button
15
+ %button{:type => "submit"} Submit
@@ -0,0 +1,99 @@
1
+ # Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
2
+
3
+ require 'pp'
4
+ require 'rubygems'
5
+ require 'bundler/setup'
6
+ #Bundler.require(:default, :test, :development) # didn't work
7
+
8
+ # development
9
+ require 'mail-store-agent'
10
+ require 'mail-single_file_delivery'
11
+ require 'haml'
12
+
13
+ # runtime
14
+ require 'rack'
15
+ require 'sinatra'
16
+ require 'thin'
17
+ require 'data_mapper'
18
+ require 'dm-types'
19
+ require 'dm-timestamps'
20
+ require 'dm-postgres-adapter'
21
+ require 'mail'
22
+ require 'logger'
23
+ require 'accounts'
24
+
25
+ class MyWebApp < Sinatra::Base
26
+ use ::Accounts::Server;
27
+
28
+ DataMapper.auto_migrate! # empty database
29
+ STDERR.puts "WARNING: called DataMapper.auto_migrate! to clear database"
30
+
31
+ enable :logging
32
+
33
+ # Web app class must define this.
34
+ # In a production environment you might want to replace this with something like Rack::Session::Pool
35
+ enable :sessions
36
+
37
+ not_found do
38
+ %Q{Page not found. Go to <a href="home">home page</a>.}
39
+ end
40
+
41
+ error 403 do
42
+ "Access denied"
43
+ end
44
+
45
+ get '/' do
46
+ %Q{Welcome visitor! Please <a href="/logon">log on</a>.}
47
+ end
48
+
49
+ get '/welcome' do
50
+ account = Accounts::Account.get(session[:account_id]) or return 403
51
+ "Welcome #{account.email}!"
52
+ end
53
+
54
+ get '/logon' do
55
+ @email = params[:email] || ''
56
+ haml :logon
57
+ end
58
+
59
+ get '/logout' do
60
+ session[:account_id] = nil
61
+ redirect to('/logon')
62
+ end
63
+
64
+ get '/register' do
65
+ haml :register
66
+ end
67
+
68
+ get '/forgot-password' do
69
+ haml :forgot_password
70
+ end
71
+
72
+ get '/change-password' do
73
+ return 403 unless session[:account_id]
74
+ haml :change_password
75
+ end
76
+
77
+ get '/change-email' do
78
+ return 403 unless session[:account_id]
79
+ haml :change_email
80
+ end
81
+
82
+ if app_file == $0
83
+ STDERR.puts "Running standalone"
84
+ # Run as stand-along web app
85
+ Mail.defaults do
86
+ delivery_method Mail::SingleFileDelivery::Agent, :filename => '/tmp/mail-test-fifo'
87
+ end
88
+ require 'sinatra/reloader'
89
+ register Sinatra::Reloader
90
+ enable :reloader
91
+ run!
92
+ else
93
+ # Probably running under Cucumber
94
+ Mail.defaults do
95
+ delivery_method(:test)
96
+ Mail::TestMailer.deliveries = MailStoreAgent.new
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
2
+
3
+ @change-email
4
+ Feature: Users can change their e-mails
5
+
6
+ @email-taken
7
+ Scenario: Alice cannot change her e-mail to one that is already taken
8
+ Given I register "alice@wunder.land" with password "caterpillar"
9
+ And I register "caterpillar@wunder.land" with password "caterpillar"
10
+ And "alice@wunder.land" is authenticated with password "caterpillar"
11
+ When Alice visits "/change-email"
12
+ And she fills in "email" with "caterpillar@wunder.land"
13
+ And she presses "Submit"
14
+ Then she should see "caterpillar@wunder.land is already taken"
15
+
16
+ @request-change-email
17
+ Scenario: Alice requests to change email to an available email
18
+ Given "alice@wunder.land" is registered with password "caterpillar"
19
+ And "alice@wunder.land" is authenticated with password "caterpillar"
20
+ When she visits "/change-email"
21
+ And she fills in "email" with "alice@looking.glass"
22
+ And she presses "Submit"
23
+ Then she should see "Check your e-mail"
24
+ And "alice@wunder.land" opens an email containing "You have requested to change your e-mail to alice@looking.glass"
25
+ And "alice@looking.glass" should receive an email
26
+
27
+ Scenario: Alice can still log on with her previous e-mail
28
+ Given "alice@wunder.land" is registered with password "caterpillar"
29
+ When she visits "/logon"
30
+ And she fills in "email" with "alice@wunder.land"
31
+ And she fills in "password" with "caterpillar"
32
+ And she presses "Submit"
33
+ Then she should be on "/welcome"
34
+ And she should see "Welcome alice@wunder.land"
35
+
36
+ Scenario: Alice follows confirmation link
37
+ Given "alice@looking.glass" opens an email containing "/response-token/"
38
+ When she visits link from email
39
+ And "email" form-input should contain "alice@looking.glass"
40
+ And she fills in "password" with "caterpillar"
41
+ And she presses "Submit"
42
+ Then she should be on "/welcome"
43
+ And she should see "Welcome alice@looking.glass"
44
+
45
+ Scenario: Alice can not log on with her previous e-mail
46
+ Given "alice@looking.glass" is registered with password "caterpillar"
47
+ When she visits "/logon"
48
+ And she fills in "email" with "alice@wunder.land"
49
+ And she fills in "password" with "caterpillar"
50
+ And she presses "Submit"
51
+ Then she should not see "Welcome alice@wunder.land"
@@ -0,0 +1,89 @@
1
+ # Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
2
+
3
+ @change-password
4
+ Feature: Users can change their passwords
5
+
6
+ @registers-confirms
7
+ Scenario: Alice requests to register
8
+ Given I have unregistered "alice@wunder.land"
9
+ When she visits "/register"
10
+ And she fills in "email" with "alice@wunder.land"
11
+ And she presses "Submit"
12
+ Then she should see "Check your e-mail"
13
+
14
+ Scenario: Alice changes her password
15
+ Given "alice@wunder.land" opens an email containing "/response-token/"
16
+ Then she visits link from email
17
+ And she should see "Change Password"
18
+ And she fills in "password" with "caterpillar"
19
+ And she fills in "password2" with "caterpillar"
20
+ And she presses "Submit"
21
+ Then she should see "You have changed your password."
22
+ And "alice@wunder.land" should receive an email
23
+ And "admin@accounts.test" should receive an email
24
+ And "admin@accounts.test" opens an email containing "alice@wunder.land has registered and confirmed"
25
+
26
+ Scenario: Alice can log on with password "caterpillar"
27
+ Given "alice@wunder.land" opens an email containing "The password for alice@wunder.land has changed."
28
+ When she visits "/logon"
29
+ And she fills in "email" with "alice@wunder.land"
30
+ And she fills in "password" with "caterpillar"
31
+ And she presses "Submit"
32
+ Then she should be on "/welcome"
33
+ And she should see "Welcome alice@wunder.land"
34
+
35
+ Scenario: Alice can not log on with password "alice"
36
+ When she visits "/logon"
37
+ And she fills in "email" with "alice@wunder.land"
38
+ And she fills in "password" with "alice"
39
+ And she presses "Submit"
40
+ Then she should be on "/logon"
41
+ And she should not see "Welcome alice@wunder.land"
42
+
43
+ Scenario: Alice attempts to visit restricted page without first authenticating
44
+ Given Alice has logged out
45
+ When she visits "/welcome"
46
+ And she should not see "Welcome alice@wunder.land"
47
+
48
+ Scenario: Alice changes her password again
49
+ Given Alice visits "/logon"
50
+ And she fills in "email" with "alice@wunder.land"
51
+ And she fills in "password" with "caterpillar"
52
+ And she presses "Submit"
53
+ And she visits "/change-password"
54
+ Then she fills in "password" with "whiterabbit"
55
+ And she fills in "password2" with "whiterabbit"
56
+ And she presses "Submit"
57
+ Then she should see "You have changed your password."
58
+
59
+ Scenario: Alice tries to log on with her defunct password
60
+ Given "alice@wunder.land" opens an email containing "The password for alice@wunder.land has changed."
61
+ When she visits "/logon"
62
+ And she fills in "email" with "alice@wunder.land"
63
+ And she fills in "password" with "caterpillar"
64
+ And she presses "Submit"
65
+ Then she should not see "Welcome alice@wunder.land"
66
+
67
+ Scenario: Only authenticated users can change their password
68
+ Given I have unregistered "dormouse@alice.com"
69
+ When he visits "/change-password"
70
+ Then he should not see "Change Password"
71
+
72
+ Scenario: Alice forgets her password
73
+ Given Alice visits "/forgot-password"
74
+ When she fills in "email" with "alice@wunder.land"
75
+ And she presses "Submit"
76
+ Then she should see "Check your e-mail"
77
+ And "alice@wunder.land" should receive an email
78
+
79
+ Scenario: Alice can reset her password again
80
+ Given "alice@wunder.land" opens an email containing "/response-token/"
81
+ When she visits link from email
82
+ Then alice should see "Change Password"
83
+ #But she remembers it again and goes to tea with Caterpillar. :)
84
+
85
+ Scenario: Unknown user attempts to reset password
86
+ Given MadHatter visits "/forgot-password"
87
+ When he fills in "email" with "madhatter@wunder.land"
88
+ And he presses "Submit"
89
+ Then he should see "madhatter@wunder.land does not match any account"
@@ -0,0 +1,42 @@
1
+ # Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
2
+
3
+ @register
4
+ Feature: Visitors can register
5
+
6
+ Scenario: Unregistered user requests to register
7
+ Given I have unregistered "alice@wunder.land"
8
+ When she visits "/register"
9
+ And she fills in "email" with "alice@wunder.land"
10
+ And she presses "Submit"
11
+ Then she should see "Check your e-mail"
12
+ And "alice@wunder.land" should receive an email
13
+
14
+ Scenario: Unconfirmed user requests to register again will get another e-mail
15
+ Given "alice@wunder.land" is registered
16
+ When she visits "/register"
17
+ And she fills in "email" with "alice@wunder.land"
18
+ And she presses "Submit"
19
+ Then page has content "Check your e-mail"
20
+ And "alice@wunder.land" should receive an email
21
+
22
+ Scenario: Confirm registration with stale link doesn't do anything
23
+ Given "alice@wunder.land" opens an email containing "/response-token/"
24
+ When she visits link from email
25
+ Then Alice should see "Page not found"
26
+ And "alice@wunder.land" is not confirmed
27
+
28
+ Scenario: Confirm registration with active link is successful
29
+ Given "alice@wunder.land" opens an email containing "/response-token/"
30
+ When she visits link from email
31
+ Then alice should see "Change Password"
32
+ And "admin@accounts.test" should receive an email
33
+ And "admin@accounts.test" opens an email containing "alice@wunder.land has registered and confirmed"
34
+ And "alice@wunder.land" is confirmed
35
+
36
+ Scenario: Confirmed user requests to register again will fail
37
+ Given "alice@wunder.land" is registered
38
+ When I visits "/register"
39
+ And I fills in "email" with "alice@wunder.land"
40
+ And I presses "Submit"
41
+ Then page has content "alice@wunder.land is already registered"
42
+ And "alice@wunder.land" should not receive an email
@@ -0,0 +1,102 @@
1
+ # Copyright Westside Consulting LLC, Ann Arbor, MI, USA, 2012
2
+
3
+ When /^page has "([^"]*)"$/ do |arg1|
4
+ #STDERR.puts page.body
5
+ page.body.should have_selector(arg1)
6
+ end
7
+
8
+ When /^page has content "([^"]*)"$/ do |arg1|
9
+ #STDERR.puts page.body
10
+ page.body.should have_content(arg1)
11
+ end
12
+
13
+ When /^"([^"]*)" is suspended$/ do |arg1|
14
+ pending # express the regexp above with the code you wish you had
15
+ end
16
+
17
+ When /^\w+ visits link from email$/ do
18
+ @new_mail.should_not be_nil
19
+ @new_mail.body.to_s =~ /(http\S+)/
20
+ link = $1
21
+ link.should_not be_nil
22
+ #STDERR.puts "link = #{link}"
23
+ visit link
24
+ end
25
+
26
+ When /^"([^"]*)" is (not )?confirmed$/ do |arg1, bool|
27
+ account = Accounts::Account.first( :email => arg1 )
28
+ should_be_confirmed = !bool
29
+
30
+ if (should_be_confirmed) then
31
+ account.should_not be_nil
32
+ account.status.should include :email_confirmed
33
+ else
34
+ account.status.should_not include :email_confirmed if account
35
+ end
36
+ end
37
+
38
+ When /^\w+ visits? "([^"]*)"$/ do |arg1|
39
+ visit arg1
40
+ #save_and_open_page
41
+ end
42
+
43
+ When /^I should see raw html: "([^"]*)"$/ do |arg1|
44
+ page.html.should match /#{arg1}/
45
+ end
46
+
47
+ When /^I have unregistered "([^"]*)"$/ do |arg1|
48
+ account = Accounts::Account.all( :email => arg1 )
49
+ account.destroy if account
50
+ Accounts::Account.all( :email => arg1 ).should have(0).items
51
+ end
52
+
53
+ When /^"([^"]*)" is (not )?registered$/ do |arg1, bool|
54
+ Accounts::Account.all( :email => arg1 ).should have(bool ? 0 : 1).items
55
+ end
56
+
57
+ When /^"([^"]*)" opens an email containing "([^"]*)"$/ do |arg1, arg2|
58
+ Mail::TestMailer.deliveries.accounts.should include(arg1)
59
+ @new_mail = Mail::TestMailer.deliveries.get(arg1)
60
+ @new_mail.should_not be_nil
61
+ @new_mail.body.should match /#{arg2}/
62
+ end
63
+
64
+ When /^"([^"]*)" should receive an email$/ do |arg1|
65
+ Mail::TestMailer.deliveries.accounts.should include(arg1)
66
+ Mail::TestMailer.deliveries.peek(arg1).should_not be_nil
67
+ end
68
+
69
+ When /^"([^"]*)" should not receive an email$/ do |arg1|
70
+ msg = Mail::TestMailer.deliveries.peek(arg1)
71
+ msg.should be_nil
72
+ end
73
+
74
+ When /^(?:\S+ )(?:is|has) logged out$/ do
75
+ visit '/logout'
76
+ end
77
+
78
+ When /^I register "([^"]*)" with password "([^"]*)"$/ do |arg1, arg2|
79
+ account = Accounts::Account.create ({ :email => arg1 })
80
+ account.set_password arg2
81
+ end
82
+
83
+ When /^"([^"]*)" is registered with password "([^"]*)"$/ do |arg1, arg2|
84
+ account = Accounts::Account.first ({ :email => arg1 })
85
+ account.should_not be_nil
86
+ account.confirm_password(arg2).should be_true
87
+ end
88
+
89
+ When /^"([^"]*)" is authenticated with password "([^"]*)"$/ do |arg1, arg2|
90
+ visit '/logon'
91
+ current_path.should be == '/logon'
92
+ fill_in('email', :with => arg1)
93
+ fill_in('password', :with => arg2)
94
+ click_button("Submit")
95
+ current_path.should be == '/welcome'
96
+ page.body.should match "Welcome #{arg1}"
97
+ end
98
+
99
+ Then /^"([^"]*)" form\-input should contain "([^"]*)"$/ do |arg1, arg2|
100
+ find("input[@name=#{arg1}]").value.should be == arg2
101
+ end
102
+