From 19deb9c398edc9e3dcb1d3a39327078528502580 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 09:27:47 +0100 Subject: [PATCH 01/10] add webrick --- Gemfile | 2 ++ Gemfile.lock | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Gemfile b/Gemfile index aa31340..90a6000 100644 --- a/Gemfile +++ b/Gemfile @@ -42,3 +42,5 @@ gem 'will_paginate', '~> 3.0' gem 'whenever', '~> 0.9', require: false gem 'mysql2', '>=0.5' gem 'base32' + +gem "webrick", "~> 1.7" # fallback for removed puma; not included in alpine diff --git a/Gemfile.lock b/Gemfile.lock index 9c5598a..a216226 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -230,6 +230,7 @@ GEM rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) + webrick (1.7.0) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -268,6 +269,7 @@ DEPENDENCIES web-console (>= 4.1.0) webdrivers webpacker (~> 5.0) + webrick (~> 1.7) whenever (~> 0.9) will_paginate (~> 3.0) From 84a78d82dfbf5bf8fb97212e77baabcdc441f430 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 09:44:09 +0100 Subject: [PATCH 02/10] fix GEM_PATH and PATH in Dockerfile.development --- Dockerfile.development | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.development b/Dockerfile.development index 3c1d20c..b5105a1 100644 --- a/Dockerfile.development +++ b/Dockerfile.development @@ -12,8 +12,8 @@ USER app ENV BUNDLE_JOBS=4 \ BUNDLE_PATH=/srv/app/vendor/bundle \ - GEM_PATH=/srv/app/vendor/bundle:$GEM_PATH \ - PATH=/srv/app/vendor/bundle/bin:$PATH + GEM_PATH=/srv/app/vendor/bundle/ruby/2.7.0:$GEM_PATH \ + PATH=/srv/app/vendor/bundle/ruby/2.7.0/bin:$PATH EXPOSE 3000 From 7257a2a5a98a21d1b0f49690845cd38e2416e376 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:07:14 +0100 Subject: [PATCH 03/10] replace database.yml by database.yml.SAMPLE (now mysql2 only) --- config/database.yml | 25 ------------------------- config/database.yml.SAMPLE | 9 +++++++++ 2 files changed, 9 insertions(+), 25 deletions(-) delete mode 100644 config/database.yml create mode 100644 config/database.yml.SAMPLE diff --git a/config/database.yml b/config/database.yml deleted file mode 100644 index 4a8a1b2..0000000 --- a/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite. Versions 3.8.0 and up are supported. -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem 'sqlite3' -# -default: &default - adapter: sqlite3 - pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> - timeout: 5000 - -development: - <<: *default - database: db/development.sqlite3 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - <<: *default - database: db/test.sqlite3 - -production: - <<: *default - database: db/production.sqlite3 diff --git a/config/database.yml.SAMPLE b/config/database.yml.SAMPLE new file mode 100644 index 0000000..99c35a7 --- /dev/null +++ b/config/database.yml.SAMPLE @@ -0,0 +1,9 @@ +development: + adapter: mysql2 + encoding: utf8 + reconnect: false + database: development + pool: 5 + username: root + password: secret + host: mysql From c19eda923e621272fbbd02d7a7a77fec999c2949 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:10:41 +0100 Subject: [PATCH 04/10] copy .gitignore from old sharedlists --- .gitignore | 68 +++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 072bcce..f50cedd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,40 +1,36 @@ -# See https://help.github.com/articles/ignoring-files for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile '~/.gitignore_global' +.bundle +.rake_tasks* +db/*.sqlite3 +log +node_modules +tmp/* +!tmp/.keep +public/assets +public/system +public/uploads +supplier_assets/** +vendor/bundle -# Ignore bundler config. -/.bundle +# no configuration +config/*.yml -# Ignore the default SQLite database. -/db/*.sqlite3 -/db/*.sqlite3-* +# IDEs, Developer tools +.idea +.loadpath +.project +.sass-cache +.rbenv-version +.get-dump.yml +.bash_history +nbproject/ +.*.sw? +*~ -# Ignore all logfiles and tempfiles. -/log/* -/tmp/* -!/log/.keep -!/tmp/.keep +coverage +tags -# Ignore pidfiles, but keep the directory. -/tmp/pids/* -!/tmp/pids/ -!/tmp/pids/.keep - -# Ignore uploaded files in development. -/storage/* -!/storage/.keep - -/public/assets -.byebug_history - -# Ignore master key for decrypting credentials and more. -/config/master.key - -/public/packs -/public/packs-test -/node_modules -/yarn-error.log -yarn-debug.log* -.yarn-integrity +# Capistrano etc. +Capfile +config/deploy +config/deploy.rb +Gemfile.capistrano* From 970fdecda78c7d2ce1206f5d81fef283e166c9b1 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:12:07 +0100 Subject: [PATCH 05/10] stop ignoring config/*.yml, but ignore config/database.yml --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index f50cedd..a26112c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,8 @@ public/uploads supplier_assets/** vendor/bundle -# no configuration -config/*.yml +# ignore database configuration, but SHARE OTHER CONFIG FILES +config/database.yml # IDEs, Developer tools .idea From fa29bc75a62ca7cc9db4980eeb16d98379e9fd44 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:12:41 +0100 Subject: [PATCH 06/10] add public/packs to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a26112c..a39048c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules tmp/* !tmp/.keep public/assets +public/packs public/system public/uploads supplier_assets/** From 6a9437cad783a660629c582260ebd5b9a181e810 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:14:31 +0100 Subject: [PATCH 07/10] rails db:schema:dump This updates the db/schema.rb from a clean development database (mariadb:10.1) using Rails 6.1. --- db/schema.rb | 118 +++++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 9583638..cf4efbd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,85 +1,81 @@ -# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # -# It's strongly recommended to check this file into your version control system. +# It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(:version => 20190811115732) do +ActiveRecord::Schema.define(version: 2019_08_11_115732) do - create_table "articles", :force => true do |t| - t.string "name", :null => false - t.integer "supplier_id", :null => false - t.string "number" - t.string "note" - t.string "manufacturer" - t.string "origin" - t.string "unit" - t.decimal "price", :precision => 8, :scale => 2, :default => 0.0, :null => false - t.decimal "tax", :precision => 3, :scale => 1, :default => 7.0, :null => false - t.decimal "deposit", :precision => 8, :scale => 2, :default => 0.0, :null => false - t.decimal "unit_quantity", :precision => 4, :scale => 1, :default => 1.0, :null => false - t.decimal "scale_quantity", :precision => 4, :scale => 2 - t.decimal "scale_price", :precision => 8, :scale => 2 + create_table "articles", charset: "utf8", force: :cascade do |t| + t.string "name", null: false + t.integer "supplier_id", null: false + t.string "number" + t.string "note" + t.string "manufacturer" + t.string "origin" + t.string "unit" + t.decimal "price", precision: 8, scale: 2, default: "0.0", null: false + t.decimal "tax", precision: 3, scale: 1, default: "7.0", null: false + t.decimal "deposit", precision: 8, scale: 2, default: "0.0", null: false + t.decimal "unit_quantity", precision: 4, scale: 1, default: "1.0", null: false + t.decimal "scale_quantity", precision: 4, scale: 2 + t.decimal "scale_price", precision: 8, scale: 2 t.datetime "created_on" t.datetime "updated_on" - t.string "category" + t.string "category" + t.index ["name"], name: "index_articles_on_name" + t.index ["number", "supplier_id"], name: "index_articles_on_number_and_supplier_id", unique: true end - add_index "articles", ["name"], :name => "index_articles_on_name" - add_index "articles", ["number", "supplier_id"], :name => "index_articles_on_number_and_supplier_id", :unique => true - - create_table "suppliers", :force => true do |t| - t.string "name", :null => false - t.string "address", :null => false - t.string "phone", :null => false - t.string "phone2" - t.string "fax" - t.string "email" - t.string "url" - t.string "delivery_days" - t.string "note" + create_table "suppliers", charset: "utf8", force: :cascade do |t| + t.string "name", null: false + t.string "address", null: false + t.string "phone", null: false + t.string "phone2" + t.string "fax" + t.string "email" + t.string "url" + t.string "delivery_days" + t.string "note" t.datetime "created_on" t.datetime "updated_on" - t.boolean "ftp_sync", :default => false - t.string "ftp_host" - t.string "ftp_user" - t.string "ftp_password" - t.string "ftp_type", :default => "bnn", :null => false - t.string "ftp_regexp", :default => "^([.]/)?PL" - t.boolean "mail_sync" - t.string "mail_from" - t.string "mail_subject" - t.string "mail_type" - t.string "salt", :null => false + t.boolean "ftp_sync", default: false + t.string "ftp_host" + t.string "ftp_user" + t.string "ftp_password" + t.string "ftp_type", default: "bnn", null: false + t.string "ftp_regexp", default: "^([.]/)?PL" + t.boolean "mail_sync" + t.string "mail_from" + t.string "mail_subject" + t.string "mail_type" + t.string "salt", null: false + t.index ["name"], name: "index_suppliers_on_name", unique: true end - add_index "suppliers", ["name"], :name => "index_suppliers_on_name", :unique => true - - create_table "user_accesses", :force => true do |t| - t.integer "user_id" - t.integer "supplier_id" + create_table "user_accesses", charset: "utf8", force: :cascade do |t| + t.integer "user_id" + t.integer "supplier_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["supplier_id"], name: "index_user_accesses_on_supplier_id" + t.index ["user_id", "supplier_id"], name: "index_user_accesses_on_user_id_and_supplier_id" + t.index ["user_id"], name: "index_user_accesses_on_user_id" end - add_index "user_accesses", ["supplier_id"], :name => "index_user_accesses_on_supplier_id" - add_index "user_accesses", ["user_id", "supplier_id"], :name => "index_user_accesses_on_user_id_and_supplier_id" - add_index "user_accesses", ["user_id"], :name => "index_user_accesses_on_user_id" - - create_table "users", :force => true do |t| - t.string "email" - t.string "password_hash" - t.string "password_salt" + create_table "users", charset: "utf8", force: :cascade do |t| + t.string "email" + t.string "password_hash" + t.string "password_salt" t.datetime "created_at" t.datetime "updated_at" - t.boolean "admin", :default => false + t.boolean "admin", default: false end end From 2470b514c21ca1cb14717d5bee5d9fd7f95755ad Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:17:27 +0100 Subject: [PATCH 08/10] add unique index on Users#email --- db/migrate/20211219074758_index_users_by_unique_email.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20211219074758_index_users_by_unique_email.rb diff --git a/db/migrate/20211219074758_index_users_by_unique_email.rb b/db/migrate/20211219074758_index_users_by_unique_email.rb new file mode 100644 index 0000000..6912b09 --- /dev/null +++ b/db/migrate/20211219074758_index_users_by_unique_email.rb @@ -0,0 +1,5 @@ +class IndexUsersByUniqueEmail < ActiveRecord::Migration[6.1] + def change + add_index :users, :email, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index cf4efbd..11b20f3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_08_11_115732) do +ActiveRecord::Schema.define(version: 2021_12_19_074758) do create_table "articles", charset: "utf8", force: :cascade do |t| t.string "name", null: false @@ -76,6 +76,7 @@ ActiveRecord::Schema.define(version: 2019_08_11_115732) do t.datetime "created_at" t.datetime "updated_at" t.boolean "admin", default: false + t.index ["email"], name: "index_users_on_email", unique: true end end From b319b9de933ba2f481f8a2d194a2a9a4c22b1014 Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:46:47 +0100 Subject: [PATCH 09/10] simplify routes --- config/routes.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index c503c42..a843a22 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,4 @@ Rails.application.routes.draw do - get 'users/new' - get 'users/show' get 'log_in' => 'sessions#new', :as => :log_in match 'log_out' => 'sessions#destroy', :as => :log_out, :via => [:get, :post] resources :sessions, :only => [:new, :create, :destroy] @@ -18,8 +16,4 @@ Rails.application.routes.draw do end resources :users - - match '/:controller(/:action(/:id))', :via => [:get, :post] - match '/users', to: 'users#index', via: 'get' - match '/users/:id', to: 'users#show', via: 'get' end From 63bc26ab1634aa14ad56099503f81fd289ef1b8b Mon Sep 17 00:00:00 2001 From: JuliusR <> Date: Sun, 19 Dec 2021 10:48:54 +0100 Subject: [PATCH 10/10] improve handling of User resource --- app/controllers/application_controller.rb | 8 ++++ app/controllers/sessions_controller.rb | 6 +-- app/controllers/users_controller.rb | 27 +++++++------ app/models/user.rb | 47 +++++++++++++---------- app/views/users/_form.haml | 1 + 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b74db76..003e661 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,6 +22,14 @@ class ApplicationController < ActionController::Base end end + def admin_required! + user = current_user + if user.nil? || !user.admin? + flash[:error] = "Not authorized!" + redirect_to root_url + end + end + def authenticate_supplier_admin! @supplier = Supplier.find((params[:supplier_id] || params[:id])) unless current_user.has_access_to?(@supplier) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index c6e9156..ceeffd3 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -6,14 +6,14 @@ class SessionsController < ApplicationController end def create - user = User.authenticate(params[:email], params[:password]) - if user + user = User.find_by(email: params[:email]) + if user && user.authenticate(params[:password]) session[:user_id] = user.id flash[:notice] = "Logged in!" redirect_to root_url else flash.now[:error] = "Invalid email or password" - render "new" + render :new end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 634633e..fab1413 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,14 +1,18 @@ class UsersController < ApplicationController + + before_action :admin_required! + def new @user=User.new end def create - @user=User.new(user_params) + @user = User.new(user_params) if @user.save - render 'show' + flash[:notice] = "Konto wurde erfolgreich erstellt." + redirect_to @user else - redirect_to new_user_path + render :new end end @@ -18,16 +22,11 @@ class UsersController < ApplicationController def update @user = User.find(params[:id]) - attrs = user_params - respond_to do |format| - if @user.update(attrs) - flash[:notice] = 'Konto wurde erfolgreich aktualisiert.' - format.html { redirect_to user_url(@user) } - format.xml { head :ok } - else - format.html { render :action => "edit" } - format.xml { render :xml => @user.errors.to_xml } - end + if @user.update(user_params) + flash[:notice] = 'Konto wurde erfolgreich aktualisiert.' + redirect_to @user + else + render :edit end end @@ -50,6 +49,6 @@ class UsersController < ApplicationController private def user_params - params.require(:user).permit(:email, :password) + params.require(:user).permit(:email, :password, :password_confirmation, :admin) end end diff --git a/app/models/user.rb b/app/models/user.rb index f37e483..1ee4371 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,38 +2,43 @@ class User < ApplicationRecord has_many :user_accesses, :dependent => :destroy has_many :suppliers, :through => :user_accesses - - attr_accessor :password - before_save :encrypt_password + attr_reader :password - validates_confirmation_of :password - validates_presence_of :password, :on => :create - validates_presence_of :email - validates_uniqueness_of :email - - def self.authenticate(email, password) - user = find_by_email(email) - if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt) - user - else - nil + validates :email, presence: true, uniqueness: true + validates :password, confirmation: true + validate do |user| + unless user.password_hash.present? && user.password_salt.present? + user.errors.add :password, :blank end end - def encrypt_password - if password.present? - self.password_salt = BCrypt::Engine.generate_salt - self.password_hash = BCrypt::Engine.hash_secret(password, password_salt) - end + def self.attributes_protected_by_default + super + %w(password_hash password_salt) end def has_access_to?(supplier) - admin? or !UserAccess.first(:conditions => {:supplier_id => supplier.id, :user_id => id}).nil? + admin? or !UserAccess.where(supplier_id: supplier.id, user_id: id).first.nil? + end + + def authenticate(password_plain) + if self.password_hash == BCrypt::Engine.hash_secret(password_plain, self.password_salt) + self + else + false + end + end + + def password=(password_plain) + @password = password_plain + unless password_plain.blank? + new_salt = BCrypt::Engine.generate_salt + self.password_hash = BCrypt::Engine.hash_secret(password_plain, new_salt) + self.password_salt = new_salt + end end def admin? !!admin end - end diff --git a/app/views/users/_form.haml b/app/views/users/_form.haml index 3c973a6..6e7e397 100644 --- a/app/views/users/_form.haml +++ b/app/views/users/_form.haml @@ -2,6 +2,7 @@ = f.input :email, required: true = f.input :password, required: true = f.input :password_confirmation, required: true + = f.input :admin, required: true .form-actions = f.submit class: 'btn'