sqlite3, test coverage improvements, auto auth

This commit is contained in:
Mark Moser 2015-10-23 19:34:59 -05:00
parent 41ceccc5b5
commit 7ddf93578e
15 changed files with 143 additions and 83 deletions

10
Gemfile
View File

@ -1,5 +1,5 @@
source 'https://rubygems.org' source 'https://rubygems.org'
ruby "2.2.2" ruby "2.2.3"
gem 'figaro', '~> 1.1.1' gem 'figaro', '~> 1.1.1'
gem 'bcrypt', '~> 3.1.7' gem 'bcrypt', '~> 3.1.7'
@ -13,19 +13,13 @@ gem 'haml-rails', "~> 0.9"
gem 'jquery-rails' gem 'jquery-rails'
gem 'json', '~> 1.8.3' gem 'json', '~> 1.8.3'
gem 'mailjet', '~> 1.1.0' gem 'mailjet', '~> 1.1.0'
gem 'mysql2', '~> 0.3.20'
gem 'responders', '~> 2.1.0' gem 'responders', '~> 2.1.0'
gem 'sass-rails', '~> 5.0' gem 'sass-rails', '~> 5.0'
gem 'sorcery', '~> 0.9.1' gem 'sorcery', '~> 0.9.1'
gem 'sqlite3', '~> 1.3.11'
gem 'twilio-ruby', '~> 4.3.0' gem 'twilio-ruby', '~> 4.3.0'
gem 'uglifier', '>= 1.3.0' gem 'uglifier', '>= 1.3.0'
# gem 'faraday'
# gem 'faraday_middleware'
# gem 'rack-protection', '~> 1.5.3'
# gem 'rabl-rails', '~> 0.4.1'
# gem 'jbuilder', '~> 2.0'
group :development, :test do group :development, :test do
gem 'awesome_print' gem 'awesome_print'
gem 'binding_of_caller' gem 'binding_of_caller'

View File

@ -71,7 +71,7 @@ GEM
erubis (2.7.0) erubis (2.7.0)
eventmachine (1.0.8) eventmachine (1.0.8)
execjs (2.6.0) execjs (2.6.0)
faraday (0.9.1) faraday (0.9.2)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
ffi (1.9.10) ffi (1.9.10)
figaro (1.1.1) figaro (1.1.1)
@ -89,9 +89,10 @@ GEM
shellany (~> 0.0) shellany (~> 0.0)
thor (>= 0.18.1) thor (>= 0.18.1)
guard-compat (1.2.1) guard-compat (1.2.1)
guard-livereload (2.4.0) guard-livereload (2.5.0)
em-websocket (~> 0.5) em-websocket (~> 0.5)
guard (~> 2.8) guard (~> 2.8)
guard-compat (~> 1.0)
multi_json (~> 1.8) multi_json (~> 1.8)
guard-minitest (2.4.4) guard-minitest (2.4.4)
guard-compat (~> 1.2) guard-compat (~> 1.2)
@ -105,7 +106,7 @@ GEM
guard-shell (0.7.1) guard-shell (0.7.1)
guard (>= 2.0.0) guard (>= 2.0.0)
guard-compat (~> 1.0) guard-compat (~> 1.0)
haml (4.0.6) haml (4.0.7)
tilt tilt
haml-rails (0.9.0) haml-rails (0.9.0)
actionpack (>= 4.0.1) actionpack (>= 4.0.1)
@ -131,7 +132,7 @@ GEM
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
json (1.8.3) json (1.8.3)
jwt (1.4.1) jwt (1.5.1)
listen (3.0.3) listen (3.0.3)
rb-fsevent (>= 0.9.3) rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9) rb-inotify (>= 0.9)
@ -145,10 +146,10 @@ GEM
rack (>= 1.4.0) rack (>= 1.4.0)
rest-client rest-client
method_source (0.8.2) method_source (0.8.2)
mime-types (2.6.1) mime-types (2.6.2)
mini_portile (0.6.2) mini_portile (0.6.2)
minitest (5.8.0) minitest (5.8.1)
minitest-reporters (1.0.16) minitest-reporters (1.1.4)
ansi ansi
builder builder
minitest (>= 5.0) minitest (>= 5.0)
@ -156,12 +157,11 @@ GEM
multi_json (1.11.2) multi_json (1.11.2)
multi_xml (0.5.5) multi_xml (0.5.5)
multipart-post (2.0.0) multipart-post (2.0.0)
mysql2 (0.3.20)
nenv (0.2.0) nenv (0.2.0)
netrc (0.10.3) netrc (0.10.3)
nokogiri (1.6.6.2) nokogiri (1.6.6.2)
mini_portile (~> 0.6.0) mini_portile (~> 0.6.0)
notiffany (0.0.7) notiffany (0.0.8)
nenv (~> 0.1) nenv (~> 0.1)
shellany (~> 0.0) shellany (~> 0.0)
oauth (0.4.7) oauth (0.4.7)
@ -171,10 +171,10 @@ GEM
multi_json (~> 1.3) multi_json (~> 1.3)
multi_xml (~> 0.5) multi_xml (~> 0.5)
rack (~> 1.2) rack (~> 1.2)
parser (2.2.2.6) parser (2.2.3.0)
ast (>= 1.1, < 3.0) ast (>= 1.1, < 3.0)
powerpack (0.1.1) powerpack (0.1.1)
pry (0.10.1) pry (0.10.3)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)
slop (~> 3.4) slop (~> 3.4)
@ -214,7 +214,7 @@ GEM
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.0.0) rainbow (2.0.0)
rake (10.4.2) rake (10.4.2)
rb-fsevent (0.9.5) rb-fsevent (0.9.6)
rb-inotify (0.9.5) rb-inotify (0.9.5)
ffi (>= 0.5.0) ffi (>= 0.5.0)
responders (2.1.0) responders (2.1.0)
@ -223,16 +223,16 @@ GEM
http-cookie (>= 1.0.2, < 2.0) http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0) mime-types (>= 1.16, < 3.0)
netrc (~> 0.7) netrc (~> 0.7)
rubocop (0.33.0) rubocop (0.34.2)
astrolabe (~> 1.3) astrolabe (~> 1.3)
parser (>= 2.2.2.5, < 3.0) parser (>= 2.2.2.5, < 3.0)
powerpack (~> 0.1) powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0) rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
ruby-progressbar (1.7.5) ruby-progressbar (1.7.5)
ruby_parser (3.6.6) ruby_parser (3.7.1)
sexp_processor (~> 4.1) sexp_processor (~> 4.1)
sass (3.4.18) sass (3.4.19)
sass-rails (5.0.4) sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0) railties (>= 4.0.0, < 5.0)
sass (~> 3.1) sass (~> 3.1)
@ -242,24 +242,25 @@ GEM
scss-lint (0.30.0) scss-lint (0.30.0)
rainbow (~> 2.0) rainbow (~> 2.0)
sass (~> 3.4.0) sass (~> 3.4.0)
sexp_processor (4.5.1) sexp_processor (4.6.0)
shellany (0.0.1) shellany (0.0.1)
slop (3.6.0) slop (3.6.0)
sorcery (0.9.1) sorcery (0.9.1)
bcrypt (~> 3.1) bcrypt (~> 3.1)
oauth (~> 0.4, >= 0.4.4) oauth (~> 0.4, >= 0.4.4)
oauth2 (>= 0.8.0) oauth2 (>= 0.8.0)
spring (1.3.6) spring (1.4.0)
sprockets (3.3.4) sprockets (3.4.0)
rack (~> 1.0) rack (> 1, < 3)
sprockets-rails (2.3.3) sprockets-rails (2.3.3)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sqlite3 (1.3.11)
sysexits (1.2.0) sysexits (1.2.0)
thin (1.6.3) thin (1.6.4)
daemons (~> 1.0, >= 1.0.9) daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0) eventmachine (~> 1.0, >= 1.0.4)
rack (~> 1.0) rack (~> 1.0)
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
@ -306,7 +307,6 @@ DEPENDENCIES
json (~> 1.8.3) json (~> 1.8.3)
mailjet (~> 1.1.0) mailjet (~> 1.1.0)
minitest-reporters minitest-reporters
mysql2 (~> 0.3.20)
pry-byebug pry-byebug
pry-rails pry-rails
rack-livereload rack-livereload
@ -316,8 +316,12 @@ DEPENDENCIES
sass-rails (~> 5.0) sass-rails (~> 5.0)
sorcery (~> 0.9.1) sorcery (~> 0.9.1)
spring spring
sqlite3 (~> 1.3.11)
thin (~> 1.6.3) thin (~> 1.6.3)
turbolinks turbolinks
twilio-ruby (~> 4.3.0) twilio-ruby (~> 4.3.0)
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
web-console (~> 2.0) web-console (~> 2.0)
BUNDLED WITH
1.10.6

View File

@ -6,16 +6,15 @@ A simple app to send sms messages with [twillio](https://www.twilio.com/).
### Secrets file: ### Secrets file:
`config/secrets.yml` is read at boot and shoves the values into `ENV`. `config/application.yml` is read at boot and shoves the values into `ENV`.
1. Copy `config/secrets.yml.sample` and rename to `config/secrets.yml`. 1. Copy `config/application.yml.sample` and rename to `config/application.yml`.
2. Edit file and set/define as many secrets as you need. The sample file has the minimum expected keys. 2. Edit file and set/define as many secrets as you need. The sample file has the minimum expected keys.
3. Make *ABSOLUTE* certain that this file is not checked into your repository. 3. Make *ABSOLUTE* certain that this file is not checked into your repository.
## TODO ## TODO
* activation flag on user edit
* sorcery or a lower oauth solution * verify roles access
* application log * application log
* app version file - milestone 0.9.0
* task runner - delayedjob or sidekiq or activerecord newness? * task runner - delayedjob or sidekiq or activerecord newness?
* milestone 1.0.0 * milestone 1.0.0

View File

@ -10,21 +10,44 @@ class OauthsController < ApplicationController
@user = login_from(provider) @user = login_from(provider)
if @user if @user
redirect_to root_path, notice: "Logged in from #{provider.titleize}!" redirect_to root_path, notice: login_msg(@user, provider)
else else
msg = "Your account must be pre-approved. Please contact the administrator." @user = auth_and_login(provider)
redirect_to root_path, notice: msg redirect_to root_path, notice: login_msg(@user, provider)
end end
end end
private private
# def create_and_login provider def login_msg user, provider = 'oAuth'
# @user = create_from(provider) if user.active?
# reset_session # protect from session fixation attack "Logged in from #{provider.titleize}!"
# auto_login(@user) else
# redirect_to root_path, notice: "Logged in from #{provider.titleize}!" "Your account must be activated by an administrator."
# end end
end
def auth_and_login provider
user = create_auth_from(provider, auth_info)
reset_session # protect from session fixation attack
auto_login(user) if user.active?
user
end
def create_auth_from provider, auth
user = Person.find_by_email auth[:user_info]["email"]
user.authentications.create(provider: provider, uid: auth[:uid])
user
end
def auth_info
@auth_info ||= google_hash
end
def google_hash
ga = Sorcery::Providers::Google.new
ga.get_user_hash access_token
end
def auth_params def auth_params
params.permit(:code, :provider) params.permit(:code, :provider)

View File

@ -1,3 +1,4 @@
class Authentication < ActiveRecord::Base class Authentication < ActiveRecord::Base
belongs_to :user belongs_to :person
validates :uid, presence: true, uniqueness: { scope: :provider }
end end

View File

@ -11,7 +11,7 @@ class Person < ActiveRecord::Base
validates :phone, presence: true validates :phone, presence: true
scope :with_name, lambda { |name| scope :with_name, lambda { |name|
where("concat(first_name, ' ', last_name) RLIKE ?", name) where("first_name || ' ' || last_name LIKE ?", "%#{name}%")
} }
scope :just_parents, lambda { scope :just_parents, lambda {
@ -34,6 +34,10 @@ class Person < ActiveRecord::Base
id id
end end
def active?
activation_state == "active"
end
private private
## SorceryCore expects the model to hold a crypted_password field ## SorceryCore expects the model to hold a crypted_password field

View File

@ -1,3 +1,3 @@
%h2 Edit #{@user.name} %h2 Edit #{@user.name}
= render partial: 'form', locals: {form_action: edit_user_path} = render partial: 'form', locals: { form_action: edit_user_path }

View File

@ -1,3 +1,3 @@
%h2 Register a new User %h2 Register a new User
= render partial: 'form', locals: {form_action: add_user_path} = render partial: 'form', locals: { form_action: add_user_path }

View File

@ -1,22 +1,19 @@
--- ---
default: &default default: &default
adapter: mysql2 adapter: sqlite3
database: db/default.sqlite3
encoding: utf8 encoding: utf8
reconnect: false
pool: 5 pool: 5
host: localhost timeout: 5000
# socket: /tmp/mysql.sock
development: development:
<<: *default <<: *default
database: sms-pager-dev database: db/development.sqlite3
test: test:
<<: *default <<: *default
database: sms-pager-test database: db/test.sqlite3
production: production:
<<: *default <<: *default
database: sms-pager-api database: db/production.sqlite3
username: <%= ENV["mysql_usr"] %>
password: <%= ENV["mysql_pwd"] %>

View File

@ -131,7 +131,7 @@ Rails.application.config.sorcery.configure do |config|
config.google.key = ENV["google_key"] config.google.key = ENV["google_key"]
config.google.secret = ENV["google_secret"] config.google.secret = ENV["google_secret"]
config.google.callback_url = "http://localhost:3000/oauth/callback?provider=google" config.google.callback_url = "http://localhost:3000/oauth/callback?provider=google"
config.google.user_info_mapping = { email: "email" } config.google.user_info_mapping = { email: "email", first_name: "given_name", last_name: "family_name" }
# config.vk.key = "" # config.vk.key = ""
# config.vk.secret = "" # config.vk.secret = ""

View File

@ -14,51 +14,51 @@
ActiveRecord::Schema.define(version: 20151008022535) do ActiveRecord::Schema.define(version: 20151008022535) do
create_table "authentications", force: :cascade do |t| create_table "authentications", force: :cascade do |t|
t.integer "person_id", limit: 4, null: false t.integer "person_id", null: false
t.string "provider", limit: 255, null: false t.string "provider", null: false
t.string "uid", limit: 255, null: false t.string "uid", null: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
add_index "authentications", ["provider", "uid"], name: "index_authentications_on_provider_and_uid", using: :btree add_index "authentications", ["provider", "uid"], name: "index_authentications_on_provider_and_uid"
create_table "children", force: :cascade do |t| create_table "children", force: :cascade do |t|
t.string "first_name", limit: 255 t.string "first_name"
t.string "last_name", limit: 255 t.string "last_name"
end end
create_table "pages", force: :cascade do |t| create_table "pages", force: :cascade do |t|
t.integer "user_id", limit: 4 t.integer "user_id"
t.integer "person_id", limit: 4 t.integer "person_id"
t.string "to", limit: 255 t.string "to"
t.string "message", limit: 255 t.string "message"
t.string "status", limit: 255 t.string "status"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
end end
create_table "parenthoods", force: :cascade do |t| create_table "parenthoods", force: :cascade do |t|
t.integer "person_id", limit: 4 t.integer "person_id"
t.integer "child_id", limit: 4 t.integer "child_id"
end end
add_index "parenthoods", ["person_id", "child_id"], name: "parentship", using: :btree add_index "parenthoods", ["person_id", "child_id"], name: "parentship"
create_table "people", force: :cascade do |t| create_table "people", force: :cascade do |t|
t.string "first_name", limit: 255 t.string "first_name"
t.string "last_name", limit: 255 t.string "last_name"
t.string "phone", limit: 255 t.string "phone"
t.string "email", limit: 255, null: false t.string "email", null: false
t.boolean "admin" t.boolean "admin"
t.boolean "staff" t.boolean "staff"
t.string "activation_state", limit: 255 t.string "activation_state"
t.string "activation_token", limit: 255 t.string "activation_token"
t.datetime "activation_token_expires_at" t.datetime "activation_token_expires_at"
end end
add_index "people", ["activation_token"], name: "index_people_on_activation_token", using: :btree add_index "people", ["activation_token"], name: "index_people_on_activation_token"
add_index "people", ["email"], name: "index_people_on_email", unique: true, using: :btree add_index "people", ["email"], name: "index_people_on_email", unique: true
add_index "people", ["phone"], name: "index_people_on_phone", using: :btree add_index "people", ["phone"], name: "index_people_on_phone"
end end

View File

@ -42,3 +42,10 @@ sarah:
email: sarah.smith@mailinator.com email: sarah.smith@mailinator.com
phone: 5005550006 phone: 5005550006
children: sally, nemo children: sally, nemo
mmoser:
first_name: Mark
last_name: Moser
email: markamoser@gmail.com
phone: 3093634474
admin: true
activation_state: active

15
test/models/child_test.rb Normal file
View File

@ -0,0 +1,15 @@
require 'test_helper'
class ChildTest < ActiveSupport::TestCase
def test_sanity
assert Child
end
def test_relations
non_relatives = Child.not_related_to people(:marlin)
smiths_count = non_relatives.where(last_name: 'smith').count
assert_equal 0, smiths_count
assert_equal 1, non_relatives.count
end
end

View File

@ -10,4 +10,19 @@ class PersonTest < ActiveSupport::TestCase
assert parents.count > 1, "Did not find more than one parent" assert parents.count > 1, "Did not find more than one parent"
end end
def test_name_first
assert_equal 1, Person.with_name('admin').count
end
def test_name_last
smiths_count = Person.where(last_name: 'Smith').count
smiths = Person.with_name 'smith'
assert_equal smiths_count, smiths.count
end
def test_name_full
assert_equal 1, Person.with_name('wanda worker').count
end
end end

1
version.md Normal file
View File

@ -0,0 +1 @@
version 0.9.0