Adds Settings and starts on Users Controllers (#1)

* Update app to run on 3000 by default instead of 5000

* handle yanked rb-fsenvent gem version

* Add user controller route

* Adds settings/users controllers

* Start adding settings table

* Adds settings creator to ensure one is created on db migrate

* whoops, validate only before creation

* Adds editing of settings

* lint

* cleanup

* Fix tests

* use the correct styling for tests

* update settings test syntax

* setting model test

* double quotes for html

* test for updating settings

* post -> patch

* Basic user list view

* using the github attr_encrypted fixes the deprecation messages for 5.1

* table view for users

* derp fix heading

* review changes

* cut out creating a setting...

* rename service class.

* update Settings form.

* add url to find slack webhook url

* fix indention

* re-organizate Settings form.

* change autofocus.

* add test/reports to gitignore
This commit is contained in:
Andrew Fomera 2017-07-14 15:15:36 -05:00 committed by GitHub
parent dfbce3da0c
commit 87ca860557
23 changed files with 271 additions and 9 deletions

2
.gitignore vendored

@ -17,3 +17,5 @@
/yarn-error.log
.byebug_history
test/reports/

@ -5,6 +5,7 @@ git_source(:github) do |repo_name|
"https://github.com/#{repo_name}.git"
end
gem 'attr_encrypted', '~> 3.0', github: 'attr-encrypted/attr_encrypted'
gem 'bootstrap', '~> 4.0.0.alpha6'
gem 'devise', '~> 4.3.0'
gem 'devise_invitable', '~> 1.7', '>= 1.7.2'

@ -1,3 +1,10 @@
GIT
remote: https://github.com/attr-encrypted/attr_encrypted.git
revision: e19445a9ae38ed9a55608d28a80e32126f30efd1
specs:
attr_encrypted (3.0.3)
encryptor (~> 3.0.0)
GEM
remote: https://rubygems.org/
specs:
@ -69,6 +76,7 @@ GEM
devise_invitable (1.7.2)
actionmailer (>= 4.1.0)
devise (>= 4.0.0)
encryptor (3.0.0)
erubi (1.6.1)
execjs (2.7.0)
factory_girl (4.8.0)
@ -203,6 +211,7 @@ PLATFORMS
ruby
DEPENDENCIES
attr_encrypted (~> 3.0)!
bootstrap (~> 4.0.0.alpha6)
byebug
capybara (~> 2.13)

@ -1 +1 @@
web: bundle exec rails server
web: bundle exec rails server -p 3000

@ -4,7 +4,7 @@ class ApplicationController < ActionController::Base
layout(:by_resource)
before_action(:configure_permitted_parameters, if: :devise_controller?)
before_action(:configure_app)
before_action(:configure_initial_account)
private
@ -16,8 +16,8 @@ class ApplicationController < ActionController::Base
devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :password])
end
def configure_app
return unless AppSetup.new(current_user, request.path).required?
def configure_initial_account
return unless InitialAccountSetup.new(current_user, request.path).required?
flash[:info] = 'Welcome to Storm! Let\'s get your app setup.'
redirect_to(new_user_registration_path)

@ -0,0 +1,31 @@
class SettingsController < ApplicationController
before_action(:authenticate_user!)
before_action(:create_settings, only: %w(edit))
def edit
@setting = Setting.first
end
def update
@setting = Setting.first
if @setting.update(setting_params)
flash[:notice] = 'Your settings have been updated.'
redirect_to root_path
else
flash[:alert] = 'Something went wrong updating settings.
Please check and try again'
render :edit
end
end
private
def setting_params
params.require(:setting).permit(:aws_key, :aws_secret, :slack_url)
end
def create_settings
SettingsCreator.execute if Setting.count.zero?
end
end

@ -0,0 +1,7 @@
class UsersController < ApplicationController
before_action(:authenticate_user!)
def index
@users = User.all
end
end

19
app/models/setting.rb Normal file

@ -0,0 +1,19 @@
class Setting < ApplicationRecord
attr_encrypted(
:aws_key,
key: Rails.application.secrets.secret_key_base.byteslice(0, 32)
)
attr_encrypted(
:aws_secret,
key: Rails.application.secrets.secret_key_base.byteslice(0, 32)
)
before_create :validate_only_one_setting_record
private
def validate_only_one_setting_record
errors.add(:base, 'There can only be one setting') if
Setting.count.positive?
end
end

@ -1,5 +1,5 @@
# AppSetup
class AppSetup
# InitialAccountSetup
class InitialAccountSetup
attr_reader(:current_user, :current_path)
def initialize(current_user, current_path)

@ -0,0 +1,6 @@
# SettingsCreator
class SettingsCreator
def self.execute
Setting.create unless Setting.count.positive?
end
end

@ -0,0 +1,39 @@
<%= form_for(@setting, url: settings_path) do |f| %>
<div class="form-group">
<%= f.label :slack_url, "Slack URL for notifications" %>
<%= f.text_field :slack_url, autofocus: true, class: "form-control" %>
<p class="form-text text-muted">
Instructions for finding your Slack URL can be found
<%= link_to "here",
"https://slack.com/apps/A0F7XDUAZ-incoming-webhooks",
target: :blank %>.
</p>
</div>
<div class="hr-sect">AWS Configuration</div>
<small class="d-block mb-3 text-muted">
Althought completely optional, configuring Storm with AWS will give
you the ability to reboot servers from Slack.
</small>
<div class="form-group">
<%= f.label :aws_key, "AWS Key" %>
<%= f.text_field :aws_key, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :aws_secret, "AWS Secret" %>
<%= f.text_field :aws_secret, class: "form-control" %>
<p class="form-text text-muted">
Instructions for finding your AWS Key and Secret can be found
<%= link_to "here", "#" %>.
</p>
</div>
<div class="form-group mb-0">
<%= f.submit "Update Settings", class: "btn btn-primary btn-block" %>
</div>
<% end %>

@ -0,0 +1,13 @@
<div class="page-heading">
<h4 class="page-title">Let's update your settings</h4>
</div>
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-block">
<%= render "form" %>
</div>
</div>
</div>
</div>

@ -2,6 +2,10 @@
<ul class="navbar-nav">
<%= nav_link("Websites", root_path) %>
<%= nav_link("Stats", "#") %>
<%= nav_link("Accounts", "#") %>
<%= nav_link("Settings", edit_settings_path) %>
<%= nav_link("Users", users_path) %>
<% if user_signed_in? %>
<%= nav_link("Sign Out", destroy_user_session_path, method: :delete) %>
<% end %>
</ul>
</nav>

@ -0,0 +1,6 @@
<tr>
<td><%= user.email %></td>
<td><%= user.created_at %></td>
<td class="td-actions">
</td>
</tr>

@ -0,0 +1,23 @@
<div class="row">
<div class="col-md-12">
<div class="card card-block">
<h4 class="card-title">Users</h4>
<div class="table-responsive">
<table class="table table-border-around mb-0">
<thead>
<tr>
<th>Email</th>
<th>Created on</th>
<th></th>
</tr>
</thead>
<tbody>
<%= render(@users) %>
</tbody>
</table>
</div>
</div>
</div>
</div>

@ -16,5 +16,7 @@ Rails.application.routes.draw do
sign_up: 'sign-up'
}
resource(:settings, only: %w(edit update))
resources(:users, only: %w(index))
resources(:websites, only: %w(new create))
end

@ -0,0 +1,17 @@
class CreateSettings < ActiveRecord::Migration[5.1]
def up
create_table :settings do |t|
t.string :slack_url
t.string :encrypted_aws_key
t.string :encrypted_aws_key_iv
t.string :encrypted_aws_secret
t.string :encrypted_aws_secret_iv
t.timestamps
end
end
def down
drop_table(:settings)
end
end

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170630210637) do
ActiveRecord::Schema.define(version: 20170714145639) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -23,6 +23,16 @@ ActiveRecord::Schema.define(version: 20170630210637) do
t.index ["website_id"], name: "index_pings_on_website_id"
end
create_table "settings", force: :cascade do |t|
t.string "slack_url"
t.string "encrypted_aws_key"
t.string "encrypted_aws_key_iv"
t.string "encrypted_aws_secret"
t.string "encrypted_aws_secret_iv"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false

@ -0,0 +1,32 @@
require 'test_helper'
class SettingsControllerTest < ActionDispatch::IntegrationTest
feature 'as as authenticated user' do
before(:each) do
@user = create(:user)
sign_in(@user)
end
test 'should get edit settings' do
get(edit_settings_url)
assert_response(:success)
end
test 'should patch update' do
# Create a setting so that one exists in the DB to update
Setting.create(aws_key: 'testing')
assert_no_difference('Setting.count') do
patch(settings_url, params: { setting: { aws_key: 'test' } })
assert_redirected_to(root_url)
end
end
end
feature 'as as an unauthenticated user' do
test 'should get redirected to sign-in' do
get(users_url)
assert_redirected_to(new_user_session_path)
end
end
end

@ -0,0 +1,22 @@
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
feature 'as as authenticated user' do
before(:each) do
@user = create(:user)
sign_in(@user)
end
test 'should get index' do
get(users_url)
assert_response(:success)
end
end
feature 'as as an unauthenticated user' do
test 'should get redirected to sign-in' do
get(users_url)
assert_redirected_to(new_user_session_path)
end
end
end

@ -35,7 +35,7 @@ class WebsitesControllerTest < ActionDispatch::IntegrationTest
end
end
feature 'as an authenticated user' do
feature 'as an unauthenticated user' do
test 'should not get index' do
assert_raise do
get('/websites')

@ -0,0 +1,4 @@
FactoryGirl.define do
factory :setting do
end
end

@ -0,0 +1,15 @@
require 'test_helper'
class SettingTest < ActiveSupport::TestCase
test 'aws_key is encrypted' do
setting = Setting.new(aws_key: 'foo')
assert(setting.save)
assert_not_nil(setting.encrypted_aws_key)
end
test 'aws_secret is encrypted' do
setting = Setting.new(aws_secret: 'foo')
assert(setting.save)
assert_not_nil(setting.encrypted_aws_secret)
end
end