accounts 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+