Add authentication and User model
* Add User model * Add SessionsController * Add password authentication on User * Request authentication for all actions except sign in * Add some helpers for ApplicationController * Update features to work with mandatory authentication
This commit is contained in:
parent
18b254e3d1
commit
7bf4d4c5f9
@ -1,3 +1,19 @@
|
|||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
protect_from_forgery
|
protect_from_forgery
|
||||||
|
|
||||||
|
before_filter :authenticate!
|
||||||
|
|
||||||
|
def current_user=(user)
|
||||||
|
session[:user_id] = user.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_user
|
||||||
|
@current_user ||= User.find(session[:user_id]) if session[:user_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def authenticate!
|
||||||
|
redirect_to new_session_path if current_user.nil?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
16
app/controllers/sessions_controller.rb
Normal file
16
app/controllers/sessions_controller.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class SessionsController < ApplicationController
|
||||||
|
skip_before_filter :authenticate!, :only => [:new, :create]
|
||||||
|
|
||||||
|
def create
|
||||||
|
user = User.authenticate(
|
||||||
|
params[:session][:email],
|
||||||
|
params[:session][:password]
|
||||||
|
)
|
||||||
|
if ! user
|
||||||
|
render 'new'
|
||||||
|
else
|
||||||
|
self.current_user = user
|
||||||
|
redirect_to :root
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
2
app/models/session.rb
Normal file
2
app/models/session.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class Session < ActiveRecord::Base
|
||||||
|
end
|
11
app/models/user.rb
Normal file
11
app/models/user.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class User < ActiveRecord::Base
|
||||||
|
validates_presence_of :email
|
||||||
|
validates_presence_of :password
|
||||||
|
|
||||||
|
def self.authenticate(email, password)
|
||||||
|
user = find_by_email(email)
|
||||||
|
return false if user.nil?
|
||||||
|
#FIXME use bcrypt
|
||||||
|
return user if user.password == password
|
||||||
|
end
|
||||||
|
end
|
6
app/views/sessions/new.html.haml
Normal file
6
app/views/sessions/new.html.haml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
= form_for(:session, :url => sessions_path) do |f|
|
||||||
|
= f.label :email
|
||||||
|
= f.text_field :email
|
||||||
|
= f.label :password
|
||||||
|
= f.password_field :password
|
||||||
|
= f.submit 'Sign in'
|
@ -1,4 +1,6 @@
|
|||||||
Scube::Application.routes.draw do
|
Scube::Application.routes.draw do
|
||||||
|
resources :sessions, :only => [:new, :create]
|
||||||
|
|
||||||
resources :tracks do
|
resources :tracks do
|
||||||
get 'stream', :on => :member
|
get 'stream', :on => :member
|
||||||
end
|
end
|
||||||
|
14
db/migrate/20110805201426_create_users.rb
Normal file
14
db/migrate/20110805201426_create_users.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class CreateUsers < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :users do |t|
|
||||||
|
t.string :email
|
||||||
|
t.string :password
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :users
|
||||||
|
end
|
||||||
|
end
|
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20110804225816) do
|
ActiveRecord::Schema.define(:version => 20110805201426) do
|
||||||
|
|
||||||
create_table "playlists", :force => true do |t|
|
create_table "playlists", :force => true do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
@ -36,4 +36,11 @@ ActiveRecord::Schema.define(:version => 20110804225816) do
|
|||||||
t.string "sha256"
|
t.string "sha256"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "users", :force => true do |t|
|
||||||
|
t.string "email"
|
||||||
|
t.string "password"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -4,6 +4,9 @@ Feature: Home
|
|||||||
As a listener
|
As a listener
|
||||||
I want to access the main features and valuable content from the homepage
|
I want to access the main features and valuable content from the homepage
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I am signed in
|
||||||
|
|
||||||
Scenario: Playlist access
|
Scenario: Playlist access
|
||||||
Given a playlist named "Electro"
|
Given a playlist named "Electro"
|
||||||
When I am on the home page
|
When I am on the home page
|
||||||
|
@ -4,6 +4,9 @@ Feature: Playlists
|
|||||||
As a listener
|
As a listener
|
||||||
I want to manage some playlists
|
I want to manage some playlists
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I am signed in
|
||||||
|
|
||||||
Scenario: List playlists
|
Scenario: List playlists
|
||||||
Given a playlist named "Electro"
|
Given a playlist named "Electro"
|
||||||
And a playlist named "Reggae"
|
And a playlist named "Reggae"
|
||||||
|
17
features/sessions.feature
Normal file
17
features/sessions.feature
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Feature: User
|
||||||
|
|
||||||
|
So that I can manage my own content
|
||||||
|
As a listener
|
||||||
|
I want the application to require a valid authentication
|
||||||
|
|
||||||
|
Scenario: Unauthenticated user
|
||||||
|
Given I am not signed in
|
||||||
|
When I go to the home page
|
||||||
|
Then I should be redirected to the sign in page
|
||||||
|
|
||||||
|
Scenario: User authentication
|
||||||
|
Given I am not signed in
|
||||||
|
When I go to the home page
|
||||||
|
Then I should be redirected to the sign in page
|
||||||
|
When I submit valid credentials
|
||||||
|
Then I should be redirected to the home page
|
26
features/step_definitions/sessions_step.rb
Normal file
26
features/step_definitions/sessions_step.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Given /^I am not signed in$/ do
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
Given /^I am signed in$/ do
|
||||||
|
user = Factory.create(:user)
|
||||||
|
visit new_session_path
|
||||||
|
fill_in('Email', :with => user.email)
|
||||||
|
fill_in('Password', :with => user.password)
|
||||||
|
click_button('Sign in')
|
||||||
|
end
|
||||||
|
|
||||||
|
Then /^I should be redirected to the sign in page$/ do
|
||||||
|
current_path.should == new_session_path
|
||||||
|
end
|
||||||
|
|
||||||
|
Then /^I should be redirected to the home page$/ do
|
||||||
|
current_path.should == root_path
|
||||||
|
end
|
||||||
|
|
||||||
|
When /^I submit valid credentials$/ do
|
||||||
|
user = Factory.create(:user)
|
||||||
|
fill_in('Email', :with => user.email)
|
||||||
|
fill_in('Password', :with => user.password)
|
||||||
|
click_button('Sign in')
|
||||||
|
end
|
@ -16,6 +16,5 @@ end
|
|||||||
|
|
||||||
Then /^it should provide an audio stream for "([^"]*)"$/ do |name|
|
Then /^it should provide an audio stream for "([^"]*)"$/ do |name|
|
||||||
page.should have_xpath "//audio[@src='#{stream_track_path(@track)}']"
|
page.should have_xpath "//audio[@src='#{stream_track_path(@track)}']"
|
||||||
get find('audio')[:src]
|
visit find('audio')[:src]
|
||||||
last_response.status.should == 200
|
|
||||||
end
|
end
|
||||||
|
@ -4,6 +4,9 @@ Feature: Tracks
|
|||||||
As a listener
|
As a listener
|
||||||
I want to add, manage and listen some tracks
|
I want to add, manage and listen some tracks
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I am signed in
|
||||||
|
|
||||||
Scenario: Show track
|
Scenario: Show track
|
||||||
Given a track named "Mega song"
|
Given a track named "Mega song"
|
||||||
When I go to the track page for "Mega song"
|
When I go to the track page for "Mega song"
|
||||||
|
21
spec/controllers/application_controller_spec.rb
Normal file
21
spec/controllers/application_controller_spec.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ApplicationController do
|
||||||
|
let(:user) { Factory.create(:user) }
|
||||||
|
|
||||||
|
describe '#current_user=' do
|
||||||
|
it 'stores the user id in the session as :user_id' do
|
||||||
|
controller.current_user = user
|
||||||
|
session[:user_id].should == user.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#current_user' do
|
||||||
|
context 'when session[:user_id] is set' do
|
||||||
|
it 'returns the User instance from the session' do
|
||||||
|
session[:user_id] = user.id
|
||||||
|
controller.current_user.should == user
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,6 +1,10 @@
|
|||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe HomeController do
|
describe HomeController do
|
||||||
|
before do
|
||||||
|
controller.current_user = Factory.create(:user)
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET index' do
|
describe 'GET index' do
|
||||||
it 'assigns all playlists as @playlists' do
|
it 'assigns all playlists as @playlists' do
|
||||||
playlist = Factory.create(:playlist)
|
playlist = Factory.create(:playlist)
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe PlaylistsController do
|
describe PlaylistsController do
|
||||||
|
before do
|
||||||
|
controller.current_user = Factory.create(:user)
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET index' do
|
describe 'GET index' do
|
||||||
it 'assigns all playlists as @playlists' do
|
it 'assigns all playlists as @playlists' do
|
||||||
playlist = Factory.create(:playlist)
|
playlist = Factory.create(:playlist)
|
||||||
|
40
spec/controllers/sessions_controller_spec.rb
Normal file
40
spec/controllers/sessions_controller_spec.rb
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe SessionsController do
|
||||||
|
describe 'GET new' do
|
||||||
|
it 'responds successfully' do
|
||||||
|
response.should be_success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST create' do
|
||||||
|
context 'when the user submit invalid credentials' do
|
||||||
|
it 'renders the new template' do
|
||||||
|
User.stub(:authenticate).and_return(false)
|
||||||
|
post :create,
|
||||||
|
:session => Factory.attributes_for(:user, :password => 'WRONG')
|
||||||
|
response.should render_template('new')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the user submit valid credentials' do
|
||||||
|
let(:user) { Factory.create(:user) }
|
||||||
|
before do
|
||||||
|
User.stub(:authenticate).and_return(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'signs the user in' do
|
||||||
|
post :create, :session => Factory.attributes_for(:user)
|
||||||
|
controller.current_user.should == user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects to the home page' do
|
||||||
|
post :create, :session => Factory.attributes_for(:user)
|
||||||
|
response.should redirect_to(:root)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE destroy' do
|
||||||
|
end
|
||||||
|
end
|
@ -1,6 +1,10 @@
|
|||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe TracksController do
|
describe TracksController do
|
||||||
|
before do
|
||||||
|
controller.current_user = Factory.create(:user)
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET show' do
|
describe 'GET show' do
|
||||||
it 'assigns the requested track as @track' do
|
it 'assigns the requested track as @track' do
|
||||||
track = Factory.create(:track)
|
track = Factory.create(:track)
|
||||||
|
@ -8,4 +8,9 @@ FactoryGirl.define do
|
|||||||
mime_type 'audio/ogg'
|
mime_type 'audio/ogg'
|
||||||
sha256 '94a5486a69a7261da350c57f9e5a1eaa789e08752cfc56a1989976a6ad82f7a8'
|
sha256 '94a5486a69a7261da350c57f9e5a1eaa789e08752cfc56a1989976a6ad82f7a8'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :user do
|
||||||
|
email 'alice@example.net'
|
||||||
|
password '733tP4s5'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
44
spec/models/user_spec.rb
Normal file
44
spec/models/user_spec.rb
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe User do
|
||||||
|
subject { user }
|
||||||
|
let(:user) { Factory.build(:user) }
|
||||||
|
|
||||||
|
context 'with valid attributes' do
|
||||||
|
it { should be_valid }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when email empty' do
|
||||||
|
before do
|
||||||
|
user.email = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should_not be_valid }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when password empty' do
|
||||||
|
before do
|
||||||
|
user.password = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should_not be_valid }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.authenticate' do
|
||||||
|
let (:user) { Factory.create(:user) }
|
||||||
|
|
||||||
|
it 'returns the user with valid credentials' do
|
||||||
|
User.authenticate(
|
||||||
|
user.email,
|
||||||
|
user.password
|
||||||
|
).should == user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns false with invalid credentials' do
|
||||||
|
User.authenticate(
|
||||||
|
user.email,
|
||||||
|
'WRONG'
|
||||||
|
).should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
spec/views/sessions/new.html.haml_spec.rb
Normal file
26
spec/views/sessions/new.html.haml_spec.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'sessions/new.html.haml' do
|
||||||
|
it 'renders a form to sign in' do
|
||||||
|
render
|
||||||
|
rendered.should \
|
||||||
|
have_selector("form[method=post][action='#{sessions_path}']")
|
||||||
|
rendered.should have_selector('input[type=submit]')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders a text field with a label for the mail address' do
|
||||||
|
render
|
||||||
|
rendered.should \
|
||||||
|
have_selector("input[type=text][name='session[email]']")
|
||||||
|
rendered.should \
|
||||||
|
have_selector('label[for=session_email]', :text => 'Email')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders a password field with a label for the password' do
|
||||||
|
render
|
||||||
|
rendered.should \
|
||||||
|
have_selector("input[type=password][name='session[password]']")
|
||||||
|
rendered.should \
|
||||||
|
have_selector('label[for=session_password]', :text => 'Password')
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user