admin_auth 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NzcwYmZlNTJmZjU4MmQ5OGY4YTI5ZTk0NjVhYzFkMjNhOGQ2NGFiZg==
5
+ data.tar.gz: !binary |-
6
+ OGE1OTdkZWVkMTRjMzQ1MGFiOTBjYmM0N2NhOWRlNjI1OTRiOTUxYg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MTk2ZmYyMDdiMjg5YzU0NTc4NzA1N2VhNTcxZjZhNGFlOTJiYzQyM2I1ZWNl
10
+ N2VhNjE2N2IyMWQzZjIxMzFhNzI3M2JkMDgwYzVlNTBmNTBhMDRmNjBiMzgw
11
+ NzhlNTNiNGMzMzMxZTBlOTYxMDljYzNmYmMxMGM5NDMzNjc0NmE=
12
+ data.tar.gz: !binary |-
13
+ ZjVkODExYjBmNTU0YWQzMWI3YWRhOWUwYjY4NTllNDQ2YjZiNjdiNTdhOWNl
14
+ ZjUwMDEyNWI5OGNhMjg5N2I0ZTM0MDRhYWYxNzc2NDA4ZDVjMGJkMjc2NmY4
15
+ NWQ1ZWQ4YzQxMmQ2ZjUyZDBkNzE4ZmJjNGNkOTI0YTgzN2RlOTk=
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.gem
16
+ /.idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
6
+ script: bundle exec rspec spec
7
+ deploy:
8
+ provider: rubygems
9
+ api_key:
10
+ secure: 2CoI5hs+BpM23Q7WrZuYoG7FRzcoRVXzfsQugOQrc2qQkQV5OaIZEL1fbO1+5kdWMxd7odKeL6CUpEpkaIw1WBVlJdMBhy4EoA3UchJ1VOA6CH0y1TkaD1vDzC8AWMDNCGxlnzfRQhCiEtcS0rN6IrJj8YBwEmj2fCk47TJ0o1o=
11
+ notifications:
12
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in admin_auth.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Phillip Boksz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # AdminAuth
2
+
3
+ This a small gem that extracts simple admin database authentication functionality.
4
+
5
+ It is written in a way that will work with both `ActiveRecord` and `Mongoid` and any other ORM that has the methods `all`, `new`, `create`, `where`, `update_attributes`, `destroy` (And they work in the same fashion).
6
+
7
+ It requires adding a few things to your code, but handles all the things related to authentication on this basic level, including controllers, views, routing, password encryption (with BCrypt).
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'admin_auth'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install admin_auth
24
+
25
+ ## Usage
26
+
27
+ To use this gem you need to do few things:
28
+
29
+ 1. Create an `Admin` model that has two fields:
30
+ - email (string)
31
+ - encrypted_password (string)
32
+ 2. Add the line `admin_auth_routes` to your `routes.rb` file.
33
+ 3. Now if you add `before_action authenticate_admin!` to any controller it will send the user to the admin login page.
34
+ 4. To create an admin you will need to do it in the rails console: `Admin.create(email: 'email@email.com', password: 'password', password_confirmation: 'password')`
35
+ 5. Optionally, add an `after_login_path` method to your `ApplicationController` that returns the path you want to redirect to when logged in.
36
+ 6. Optionally, add an `after_logout_path` method to your `ApplicationController` that returns the path you want to redirect to after logout.
37
+ 7. Optionally, you can copy the views in the gem to `app/views/admin` and modify then how you see fit.
38
+
39
+ ## Contributing
40
+
41
+ 1. Fork it ( https://github.com/[my-github-username]/admin_auth/fork )
42
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
43
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
44
+ 4. Push to the branch (`git push origin my-new-feature`)
45
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'admin_auth/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "admin_auth"
8
+ spec.version = AdminAuth::VERSION
9
+ spec.authors = ["Phillip Boksz"]
10
+ spec.email = ["pboksz@gmail.com"]
11
+ spec.summary = "A gem that helps with basic database authentication."
12
+ spec.description = spec.summary
13
+ spec.license = "MIT"
14
+ spec.homepage = "https://github.com/pboksz/admin_auth"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ spec.required_ruby_version = ">= 1.9"
21
+
22
+ spec.add_dependency "bcrypt", "~> 3"
23
+ spec.add_dependency "haml", "~> 4"
24
+ spec.add_dependency "rails", "~> 4"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.7"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "pry", "~> 0"
29
+ spec.add_development_dependency "rspec", "~> 3"
30
+ end
@@ -0,0 +1,45 @@
1
+ class Admin::AdminsController < ::ApplicationController
2
+ before_action :authenticate_admin!
3
+
4
+ def index
5
+ render :index, locals: { admins: admins_repository.all }
6
+ end
7
+
8
+ def new
9
+ render :new, locals: { admin: admins_repository.new }
10
+ end
11
+
12
+ def create
13
+ admin = admins_repository.create(create_params)
14
+
15
+ if admin.persisted?
16
+ redirect_to admin_admins_path(locale)
17
+ else
18
+ render :new, locals: { admin: admin }
19
+ end
20
+ end
21
+
22
+ def edit
23
+ render :edit, locals: { admin: admins_repository.find(params[:id]) }
24
+ end
25
+
26
+ def update
27
+ admins_repository.update(params[:id], update_params)
28
+ redirect_to admin_admins_path(locale)
29
+ end
30
+
31
+ def destroy
32
+ admins_repository.destroy(params[:id])
33
+ redirect_to admin_admins_path(locale)
34
+ end
35
+
36
+ private
37
+
38
+ def create_params
39
+ params.require(:admin).permit(:email, :password, :password_confirmation)
40
+ end
41
+
42
+ def update_params
43
+ params.require(:admin).permit(:password, :password_confirmation)
44
+ end
45
+ end
@@ -0,0 +1,41 @@
1
+ class Admin::SessionsController < ::ApplicationController
2
+ def new
3
+ if current_admin
4
+ redirect_to after_login_path(locale)
5
+ else
6
+ render :new, locals: { admin: admins_repository.new }
7
+ end
8
+ end
9
+
10
+ def create
11
+ admin = admins_repository.find(email: create_params[:email])
12
+
13
+ if admin && admin.correct_password?(create_params[:password])
14
+ create_admin_session(admin)
15
+ redirect_to after_login_path(locale)
16
+ else
17
+ render :new, locals: { admin: admins_repository.new }
18
+ end
19
+ end
20
+
21
+ def destroy
22
+ destroy_admin_session
23
+ redirect_to after_logout_path(locale)
24
+ end
25
+
26
+ private
27
+
28
+ def create_admin_session(admin)
29
+ @current_admin = admin
30
+ session[:admin_id] = admin.id.to_s
31
+ end
32
+
33
+ def destroy_admin_session
34
+ @current_admin = nil
35
+ session[:admin_id] = nil
36
+ end
37
+
38
+ def create_params
39
+ params.require(:admin).permit(:email, :password)
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ .admin-auth.edit
2
+ %h2= 'Edit admin'
3
+ = form_for admin, url: admin_admin_path(locale, admin), method: :put do |f|
4
+ = f.password_field :password, placeholder: '********'
5
+ = f.password_field :password_confirmation, placeholder: '********'
6
+ = f.submit 'Save'
@@ -0,0 +1,21 @@
1
+ .admin-auth.index
2
+ %h2= 'Admins'
3
+ .action
4
+ = link_to 'Add an Admin', new_admin_admin_path(locale), class: 'button'
5
+ = link_to 'Change your password', edit_admin_admin_path(locale, current_admin), class: 'button'
6
+
7
+ %table
8
+ %thead
9
+ %tr
10
+ %td= 'Email'
11
+ %td= 'Sign in count'
12
+ %td= 'Last signed in at'
13
+ %td= 'Actions'
14
+ %tbody
15
+ - admins.each do |admin|
16
+ %tr
17
+ %td= admin.email
18
+ %td= admin.sign_in_count
19
+ %td= admin.last_sign_in_at
20
+ %td.action= link_to 'Delete', admin_admin_path(locale, admin), method: :delete,
21
+ data: { confirm: 'Are you sure?' }, class: 'button'
@@ -0,0 +1,7 @@
1
+ .admin-auth.new
2
+ %h2= 'New admin'
3
+ = form_for admin, url: admin_admins_path(locale), method: :post do |f|
4
+ = f.text_field :email, placeholder: 'email@email.com'
5
+ = f.password_field :password, placeholder: '********'
6
+ = f.password_field :password_confirmation, placeholder: '********'
7
+ = f.submit 'Save'
@@ -0,0 +1,6 @@
1
+ .admin-auth.login
2
+ %h2= 'Admin login'
3
+ = form_for admin, url: admin_login_path(locale), method: :post do |f|
4
+ = f.text_field :email, placeholder: 'email@email.com'
5
+ = f.password_field :password, placeholder: '********'
6
+ = f.submit 'Login'
data/lib/admin_auth.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'admin_auth/controller'
2
+ require 'admin_auth/encryptor'
3
+ require 'admin_auth/model'
4
+ require 'admin_auth/repository'
5
+ require 'admin_auth/routes'
6
+ require 'admin_auth/version'
7
+
8
+ module AdminAuth
9
+ class Engine < ::Rails::Engine
10
+ config.autoload_paths += Dir["#{config.root}/app/**/*.rb"]
11
+ end
12
+
13
+ class Railtie < ::Rails::Railtie
14
+ initializer :admin_auth do
15
+ Admin.include(AdminAuth::Model)
16
+ ApplicationController.include(AdminAuth::Controller)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ module AdminAuth
2
+ module Controller
3
+ def self.included(controller)
4
+ controller.helper_method :current_admin
5
+ controller.helper_method :locale
6
+ end
7
+
8
+ def authenticate_admin!
9
+ redirect_to admin_login_path(locale) unless current_admin
10
+ end
11
+
12
+ def current_admin
13
+ @current_admin ||= admins_repository.find(id: session[:admin_id]) if session[:admin_id]
14
+ end
15
+
16
+ def locale
17
+ params[:locale]
18
+ end
19
+
20
+ def after_login_path(new_locale = locale)
21
+ admin_admins_path(new_locale)
22
+ end
23
+
24
+ def after_logout_path(new_locale = locale)
25
+ admin_root_path(new_locale)
26
+ end
27
+
28
+ private
29
+
30
+ def admins_repository
31
+ @admins_repository ||= Repository.new
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module AdminAuth
2
+ class Encryptor
3
+ require 'bcrypt'
4
+
5
+ def encrypt_password(password)
6
+ create_encrypted_password(password)
7
+ end
8
+
9
+ def compare_passwords?(password, encrypted_password)
10
+ salt = encrypted_salt(encrypted_password)
11
+ hashed_password = encrypted_password(password, salt)
12
+
13
+ compare_passwords(hashed_password, encrypted_password)
14
+ end
15
+
16
+ private
17
+
18
+ def create_encrypted_password(password)
19
+ BCrypt::Password.create(password, cost: 10)
20
+ end
21
+
22
+ def encrypted_salt(encrypted_password)
23
+ BCrypt::Password.new(encrypted_password).salt
24
+ end
25
+
26
+ def encrypted_password(password, salt)
27
+ BCrypt::Engine.hash_secret(password, salt)
28
+ end
29
+
30
+ def compare_passwords(hashed_password, encrypted_password)
31
+ Rack::Utils.secure_compare(hashed_password, encrypted_password)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ module AdminAuth
2
+ module Model
3
+ EMAIL_REGEX = /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/
4
+ PASSWORD_MINIMUM = 8
5
+
6
+ def self.included(model)
7
+ model.validates :email, format: { with: EMAIL_REGEX }
8
+ model.validates :password, :password_confirmation, length: { minimum: PASSWORD_MINIMUM }
9
+ model.validate :passwords_must_match
10
+ end
11
+
12
+ def password
13
+ @password
14
+ end
15
+
16
+ def password=(password)
17
+ @password = password
18
+ self.encrypted_password = password_encryptor.encrypt_password(password)
19
+ end
20
+
21
+ def password_confirmation
22
+ @password_confirmation
23
+ end
24
+
25
+ def password_confirmation=(password)
26
+ @password_confirmation = password
27
+ end
28
+
29
+ def correct_password?(password)
30
+ password_encryptor.compare_passwords?(password, encrypted_password)
31
+ end
32
+
33
+ private
34
+
35
+ def passwords_must_match
36
+ unless @password == @password_confirmation
37
+ error = 'must match'
38
+ errors[:password] << error
39
+ errors[:password_confirmation] << error
40
+ end
41
+
42
+ clear_passwords
43
+ end
44
+
45
+ def clear_passwords
46
+ @password = @password_confirmation = nil
47
+ end
48
+
49
+ def password_encryptor
50
+ @password_encryptor ||= Encryptor.new
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,36 @@
1
+ module AdminAuth
2
+ class Repository
3
+ attr_reader :klass
4
+
5
+ def initialize
6
+ @klass = Admin
7
+ end
8
+
9
+ def all
10
+ klass.all
11
+ end
12
+
13
+ def new(attributes = {})
14
+ klass.new(attributes)
15
+ end
16
+
17
+ def create(attributes)
18
+ klass.create(attributes)
19
+ end
20
+
21
+ def find(attributes)
22
+ klass.where(attributes).first
23
+ end
24
+
25
+ def update(id, attributes)
26
+ model = find(id: id)
27
+ model.update_attributes(attributes)
28
+
29
+ model
30
+ end
31
+
32
+ def destroy(id)
33
+ find(id: id).destroy
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ def admin_auth_routes
4
+ scope '(:locale)' do
5
+ namespace :admin do
6
+ get '/login', to: 'sessions#new'
7
+ post '/login', to: 'sessions#create'
8
+ get '/logout', to: 'sessions#destroy'
9
+
10
+ resources :admins
11
+
12
+ root 'sessions#new'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module AdminAuth
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminAuth::Controller do
4
+ class Controller < ActionController::Base
5
+ include AdminAuth::Controller
6
+ end
7
+
8
+ subject { Controller.new }
9
+
10
+ let(:params) { {} }
11
+ before do
12
+ subject.params = params
13
+ end
14
+
15
+ describe '#authenticate_admin!' do
16
+ describe 'current admin present' do
17
+ before do
18
+ expect(subject).to receive(:current_admin).and_return(double)
19
+ expect(subject).to receive(:redirect_to).never
20
+ end
21
+
22
+ it { expect(subject.authenticate_admin!) }
23
+ end
24
+
25
+ describe 'current admin nil' do
26
+ let(:admin_login_path) { 'admin/login' }
27
+ before do
28
+ expect(subject).to receive(:current_admin).and_return(nil)
29
+ expect(subject).to receive(:admin_login_path).and_return(admin_login_path)
30
+ expect(subject).to receive(:redirect_to).with(admin_login_path)
31
+ end
32
+
33
+ it { expect(subject.authenticate_admin!) }
34
+ end
35
+ end
36
+
37
+ describe '#current_admin' do
38
+ describe 'session has admin id' do
39
+ let(:admin) { double(id: 1) }
40
+ let(:admins_repository) { double }
41
+ before do
42
+ allow(subject).to receive(:session).and_return({ admin_id: admin.id })
43
+ expect(subject).to receive(:admins_repository).and_return(admins_repository)
44
+ expect(admins_repository).to receive(:find).with(id: admin.id).and_return(admin)
45
+ end
46
+
47
+ it { expect(subject.current_admin).to eq admin }
48
+ end
49
+
50
+ describe 'session does not have admin id' do
51
+ before { allow(subject).to receive(:session).and_return({}) }
52
+ it { expect(subject.current_admin).to be_nil }
53
+ end
54
+ end
55
+
56
+ describe '#locale' do
57
+ describe 'no locale in params' do
58
+ it { expect(subject.locale).to be_nil }
59
+ end
60
+
61
+ describe 'locale in params' do
62
+ let(:params) { { locale: :en } }
63
+ it { expect(subject.locale).to eq :en }
64
+ end
65
+ end
66
+
67
+ describe '#after_login_path' do
68
+ describe 'no locale in params' do
69
+ before { expect(subject).to receive(:admin_admins_path).with(nil) }
70
+ it { subject.after_login_path }
71
+ end
72
+
73
+ describe 'locale in params' do
74
+ let(:params) { { locale: :en } }
75
+
76
+ describe 'no locale passed' do
77
+ before { expect(subject).to receive(:admin_admins_path).with(:en) }
78
+ it { subject.after_login_path }
79
+ end
80
+
81
+ describe 'locale passed' do
82
+ before { expect(subject).to receive(:admin_admins_path).with(:pl) }
83
+ it { subject.after_login_path(:pl) }
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#after_logout_path' do
89
+ before { subject.params = { locale: :en } }
90
+
91
+ describe 'no locale passed' do
92
+ before { expect(subject).to receive(:admin_root_path).with(:en) }
93
+ it { subject.after_logout_path }
94
+ end
95
+
96
+ describe 'locale passed' do
97
+ before { expect(subject).to receive(:admin_root_path).with(:pl) }
98
+ it { subject.after_logout_path(:pl) }
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminAuth::Encryptor do
4
+ subject { AdminAuth::Encryptor.new }
5
+
6
+ describe '#encrypt_password' do
7
+ let(:password) { double }
8
+ let(:encrypted_password) { double }
9
+ before { expect(BCrypt::Password).to receive(:create).with(password, cost: 10).and_return(encrypted_password) }
10
+
11
+ it { expect(subject.encrypt_password(password)).to eq encrypted_password }
12
+ end
13
+
14
+ describe '#compare_passwords?' do
15
+ let(:password) { double }
16
+ let(:encrypted_password) { double }
17
+ let(:salt) { double }
18
+ let(:bcrypt) { double(salt: salt) }
19
+ let(:hashed_password) { double }
20
+ before do
21
+ expect(BCrypt::Password).to receive(:new).with(encrypted_password).and_return(bcrypt)
22
+ expect(BCrypt::Engine).to receive(:hash_secret).with(password, salt).and_return(hashed_password)
23
+ expect(Rack::Utils).to receive(:secure_compare).with(hashed_password, encrypted_password).and_return(true)
24
+ end
25
+
26
+ it { expect(subject.compare_passwords?(password, encrypted_password)).to eq true }
27
+ end
28
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminAuth::Model do
4
+ class Admin
5
+ include ActiveModel::Model
6
+ include AdminAuth::Model
7
+
8
+ attr_accessor :email, :encrypted_password
9
+ end
10
+
11
+ let(:email) { 'email@email.com' }
12
+ let(:password) { '12345678' }
13
+ let(:password_confirmation) { password }
14
+ let(:attributes) { { email: email, password: password, password_confirmation: password_confirmation } }
15
+ subject { Admin.new(attributes) }
16
+
17
+ describe 'validations' do
18
+ describe 'email format' do
19
+ describe 'blank' do
20
+ let(:email) { '' }
21
+ it { expect(subject).not_to be_valid }
22
+ end
23
+
24
+ describe 'just a string' do
25
+ let(:email) { 'email' }
26
+ it { expect(subject).not_to be_valid }
27
+ end
28
+
29
+ describe 'missing domain' do
30
+ let(:email) { 'email@email' }
31
+ it { expect(subject).not_to be_valid }
32
+ end
33
+
34
+ describe 'full email' do
35
+ let(:email) { 'email@email.com' }
36
+ it { expect(subject).to be_valid }
37
+ end
38
+ end
39
+
40
+ describe 'password length' do
41
+ describe 'blank' do
42
+ let(:password) { '' }
43
+ it { expect(subject).not_to be_valid }
44
+ end
45
+
46
+ describe 'too short' do
47
+ let(:password) { '1234' }
48
+ it { expect(subject).not_to be_valid }
49
+ end
50
+
51
+ describe 'a least 8 characters' do
52
+ let(:password) { '12345678' }
53
+ it { expect(subject).to be_valid }
54
+ end
55
+ end
56
+
57
+ describe 'password confirmation length' do
58
+ describe 'blank' do
59
+ let(:password_confirmation) { '' }
60
+ it { expect(subject).not_to be_valid }
61
+ end
62
+
63
+ describe 'too short' do
64
+ let(:password_confirmation) { '1234' }
65
+ it { expect(subject).not_to be_valid }
66
+ end
67
+
68
+ describe 'a least 8 characters' do
69
+ let(:password_confirmation) { '12345678' }
70
+ it { expect(subject).to be_valid }
71
+ end
72
+ end
73
+
74
+ describe 'passwords must match' do
75
+ describe 'they match' do
76
+ it { expect(subject).to be_valid }
77
+ end
78
+
79
+ describe 'they do not match' do
80
+ let(:password_confirmation) { 'invalid' }
81
+ it { expect(subject).not_to be_valid }
82
+ end
83
+
84
+ describe 'clears passwords after check' do
85
+ before { subject.valid? }
86
+ it { expect(subject.password).to be_nil }
87
+ it { expect(subject.password_confirmation).to be_nil }
88
+ end
89
+ end
90
+ end
91
+
92
+ describe 'instance methods' do
93
+ let(:password_encryptor) { double }
94
+ let(:encrypted_password) { double }
95
+
96
+ describe '#password' do
97
+ it { expect(subject.password).to eq password }
98
+ end
99
+
100
+ describe '#password=' do
101
+ before do
102
+ allow(AdminAuth::Encryptor).to receive(:new).and_return(password_encryptor)
103
+ expect(password_encryptor).to receive(:encrypt_password).with(password).and_return(encrypted_password)
104
+ end
105
+
106
+ it { expect(subject.password).to eq password }
107
+ it { expect(subject.encrypted_password).to eq encrypted_password }
108
+ end
109
+
110
+ describe '#password_confirmation' do
111
+ it { expect(subject.password_confirmation).to eq password }
112
+ end
113
+
114
+ describe '#password_confirmation=' do
115
+ before { subject.password_confirmation = password }
116
+ it { expect(subject.password_confirmation).to eq password }
117
+ end
118
+
119
+ describe '#correct_password?' do
120
+ before do
121
+ allow(AdminAuth::Encryptor).to receive(:new).and_return(password_encryptor)
122
+ expect(password_encryptor).to receive(:encrypt_password).with(password).and_return(encrypted_password)
123
+ expect(password_encryptor).to receive(:compare_passwords?).with(password, encrypted_password).and_return(true)
124
+ end
125
+
126
+ it { expect(subject.correct_password?(password)).to eq true }
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminAuth::Repository do
4
+ class Admin; end
5
+
6
+ let(:admin) { double(id: 1) }
7
+ let(:admins) { [admin] }
8
+ let(:attributes) { { id: admin.id } }
9
+ subject { AdminAuth::Repository.new }
10
+
11
+ describe '#all' do
12
+ before { expect(Admin).to receive(:all).and_return(admins) }
13
+ it { expect(subject.all).to eq admins }
14
+ end
15
+
16
+ describe '#new' do
17
+ describe 'no attributes' do
18
+ before { expect(Admin).to receive(:new).with({}).and_return(admin) }
19
+ it { expect(subject.new).to eq admin }
20
+ end
21
+
22
+ describe 'with attributes' do
23
+ before { expect(Admin).to receive(:new).with(attributes).and_return(admin) }
24
+ it { expect(subject.new(attributes)).to eq admin }
25
+ end
26
+ end
27
+
28
+ describe '#create' do
29
+ before { expect(Admin).to receive(:create).with(attributes).and_return(admin) }
30
+ it { expect(subject.create(attributes)).to eq admin }
31
+ end
32
+
33
+ describe '#find' do
34
+ before { expect(Admin).to receive(:where).with(attributes).and_return([admin]) }
35
+ it { expect(subject.find(attributes)).to eq admin }
36
+ end
37
+
38
+ describe '#update' do
39
+ before do
40
+ expect(subject).to receive(:find).with(id: admin.id).and_return(admin)
41
+ expect(admin).to receive(:update_attributes).with(attributes)
42
+ end
43
+
44
+ it { expect(subject.update(admin.id, attributes)).to eq admin }
45
+ end
46
+
47
+ describe '#destroy' do
48
+ before do
49
+ expect(subject).to receive(:find).with(id: admin.id).and_return(admin)
50
+ expect(admin).to receive(:destroy).and_return(admin)
51
+ end
52
+
53
+ it { expect(subject.destroy(admin.id)).to eq admin }
54
+ end
55
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActionDispatch::Routing::Mapper do
4
+ let(:set) { double(resources_path_names: []) }
5
+ subject { ActionDispatch::Routing::Mapper.new(set) }
6
+
7
+ describe '#admin_auth_routes' do
8
+ it { expect(subject.respond_to?(:admin_auth_routes)).to eq true }
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'rails/all'
5
+ require 'admin_auth'
6
+
7
+ RSpec.configure do |config|
8
+ # some (optional) config here
9
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: admin_auth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Phillip Boksz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bcrypt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: haml
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '3'
111
+ description: A gem that helps with basic database authentication.
112
+ email:
113
+ - pboksz@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - .travis.yml
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - admin_auth.gemspec
126
+ - app/controllers/admin/admins_controller.rb
127
+ - app/controllers/admin/sessions_controller.rb
128
+ - app/views/admin/admins/edit.haml
129
+ - app/views/admin/admins/index.haml
130
+ - app/views/admin/admins/new.haml
131
+ - app/views/admin/sessions/new.haml
132
+ - lib/admin_auth.rb
133
+ - lib/admin_auth/controller.rb
134
+ - lib/admin_auth/encryptor.rb
135
+ - lib/admin_auth/model.rb
136
+ - lib/admin_auth/repository.rb
137
+ - lib/admin_auth/routes.rb
138
+ - lib/admin_auth/version.rb
139
+ - spec/lib/admin_auth/controller_spec.rb
140
+ - spec/lib/admin_auth/encryptor_spec.rb
141
+ - spec/lib/admin_auth/model_spec.rb
142
+ - spec/lib/admin_auth/repository_spec.rb
143
+ - spec/lib/admin_auth/routes_spec.rb
144
+ - spec/spec_helper.rb
145
+ homepage: https://github.com/pboksz/admin_auth
146
+ licenses:
147
+ - MIT
148
+ metadata: {}
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '1.9'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ requirements: []
164
+ rubyforge_project:
165
+ rubygems_version: 2.4.5
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: A gem that helps with basic database authentication.
169
+ test_files:
170
+ - spec/lib/admin_auth/controller_spec.rb
171
+ - spec/lib/admin_auth/encryptor_spec.rb
172
+ - spec/lib/admin_auth/model_spec.rb
173
+ - spec/lib/admin_auth/repository_spec.rb
174
+ - spec/lib/admin_auth/routes_spec.rb
175
+ - spec/spec_helper.rb