Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
|
63bc26ab16 | ||
|
b319b9de93 | ||
|
2470b514c2 | ||
|
6a9437cad7 | ||
|
fa29bc75a6 | ||
|
970fdecda7 | ||
|
c19eda923e | ||
|
7257a2a5a9 | ||
|
84a78d82df | ||
|
19deb9c398 |
14 changed files with 162 additions and 168 deletions
69
.gitignore
vendored
69
.gitignore
vendored
|
@ -1,40 +1,37 @@
|
||||||
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
.bundle
|
||||||
#
|
.rake_tasks*
|
||||||
# If you find yourself ignoring temporary files generated by your text editor
|
db/*.sqlite3
|
||||||
# or operating system, you probably want to add a global ignore instead:
|
log
|
||||||
# git config --global core.excludesfile '~/.gitignore_global'
|
node_modules
|
||||||
|
tmp/*
|
||||||
|
!tmp/.keep
|
||||||
|
public/assets
|
||||||
|
public/packs
|
||||||
|
public/system
|
||||||
|
public/uploads
|
||||||
|
supplier_assets/**
|
||||||
|
vendor/bundle
|
||||||
|
|
||||||
# Ignore bundler config.
|
# ignore database configuration, but SHARE OTHER CONFIG FILES
|
||||||
/.bundle
|
config/database.yml
|
||||||
|
|
||||||
# Ignore the default SQLite database.
|
# IDEs, Developer tools
|
||||||
/db/*.sqlite3
|
.idea
|
||||||
/db/*.sqlite3-*
|
.loadpath
|
||||||
|
.project
|
||||||
|
.sass-cache
|
||||||
|
.rbenv-version
|
||||||
|
.get-dump.yml
|
||||||
|
.bash_history
|
||||||
|
nbproject/
|
||||||
|
.*.sw?
|
||||||
|
*~
|
||||||
|
|
||||||
# Ignore all logfiles and tempfiles.
|
coverage
|
||||||
/log/*
|
tags
|
||||||
/tmp/*
|
|
||||||
!/log/.keep
|
|
||||||
!/tmp/.keep
|
|
||||||
|
|
||||||
# Ignore pidfiles, but keep the directory.
|
# Capistrano etc.
|
||||||
/tmp/pids/*
|
Capfile
|
||||||
!/tmp/pids/
|
config/deploy
|
||||||
!/tmp/pids/.keep
|
config/deploy.rb
|
||||||
|
Gemfile.capistrano*
|
||||||
# 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
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ USER app
|
||||||
|
|
||||||
ENV BUNDLE_JOBS=4 \
|
ENV BUNDLE_JOBS=4 \
|
||||||
BUNDLE_PATH=/srv/app/vendor/bundle \
|
BUNDLE_PATH=/srv/app/vendor/bundle \
|
||||||
GEM_PATH=/srv/app/vendor/bundle:$GEM_PATH \
|
GEM_PATH=/srv/app/vendor/bundle/ruby/2.7.0:$GEM_PATH \
|
||||||
PATH=/srv/app/vendor/bundle/bin:$PATH
|
PATH=/srv/app/vendor/bundle/ruby/2.7.0/bin:$PATH
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -42,3 +42,5 @@ gem 'will_paginate', '~> 3.0'
|
||||||
gem 'whenever', '~> 0.9', require: false
|
gem 'whenever', '~> 0.9', require: false
|
||||||
gem 'mysql2', '>=0.5'
|
gem 'mysql2', '>=0.5'
|
||||||
gem 'base32'
|
gem 'base32'
|
||||||
|
|
||||||
|
gem "webrick", "~> 1.7" # fallback for removed puma; not included in alpine
|
||||||
|
|
|
@ -230,6 +230,7 @@ GEM
|
||||||
rack-proxy (>= 0.6.1)
|
rack-proxy (>= 0.6.1)
|
||||||
railties (>= 5.2)
|
railties (>= 5.2)
|
||||||
semantic_range (>= 2.3.0)
|
semantic_range (>= 2.3.0)
|
||||||
|
webrick (1.7.0)
|
||||||
websocket-driver (0.7.5)
|
websocket-driver (0.7.5)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
|
@ -268,6 +269,7 @@ DEPENDENCIES
|
||||||
web-console (>= 4.1.0)
|
web-console (>= 4.1.0)
|
||||||
webdrivers
|
webdrivers
|
||||||
webpacker (~> 5.0)
|
webpacker (~> 5.0)
|
||||||
|
webrick (~> 1.7)
|
||||||
whenever (~> 0.9)
|
whenever (~> 0.9)
|
||||||
will_paginate (~> 3.0)
|
will_paginate (~> 3.0)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,14 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
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!
|
def authenticate_supplier_admin!
|
||||||
@supplier = Supplier.find((params[:supplier_id] || params[:id]))
|
@supplier = Supplier.find((params[:supplier_id] || params[:id]))
|
||||||
unless current_user.has_access_to?(@supplier)
|
unless current_user.has_access_to?(@supplier)
|
||||||
|
|
|
@ -6,14 +6,14 @@ class SessionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
user = User.authenticate(params[:email], params[:password])
|
user = User.find_by(email: params[:email])
|
||||||
if user
|
if user && user.authenticate(params[:password])
|
||||||
session[:user_id] = user.id
|
session[:user_id] = user.id
|
||||||
flash[:notice] = "Logged in!"
|
flash[:notice] = "Logged in!"
|
||||||
redirect_to root_url
|
redirect_to root_url
|
||||||
else
|
else
|
||||||
flash.now[:error] = "Invalid email or password"
|
flash.now[:error] = "Invalid email or password"
|
||||||
render "new"
|
render :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
|
|
||||||
|
before_action :admin_required!
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@user=User.new
|
@user=User.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@user=User.new(user_params)
|
@user = User.new(user_params)
|
||||||
if @user.save
|
if @user.save
|
||||||
render 'show'
|
flash[:notice] = "Konto wurde erfolgreich erstellt."
|
||||||
|
redirect_to @user
|
||||||
else
|
else
|
||||||
redirect_to new_user_path
|
render :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -18,16 +22,11 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
attrs = user_params
|
if @user.update(user_params)
|
||||||
respond_to do |format|
|
flash[:notice] = 'Konto wurde erfolgreich aktualisiert.'
|
||||||
if @user.update(attrs)
|
redirect_to @user
|
||||||
flash[:notice] = 'Konto wurde erfolgreich aktualisiert.'
|
else
|
||||||
format.html { redirect_to user_url(@user) }
|
render :edit
|
||||||
format.xml { head :ok }
|
|
||||||
else
|
|
||||||
format.html { render :action => "edit" }
|
|
||||||
format.xml { render :xml => @user.errors.to_xml }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -50,6 +49,6 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
def user_params
|
def user_params
|
||||||
params.require(:user).permit(:email, :password)
|
params.require(:user).permit(:email, :password, :password_confirmation, :admin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,37 +3,42 @@ class User < ApplicationRecord
|
||||||
has_many :user_accesses, :dependent => :destroy
|
has_many :user_accesses, :dependent => :destroy
|
||||||
has_many :suppliers, :through => :user_accesses
|
has_many :suppliers, :through => :user_accesses
|
||||||
|
|
||||||
|
attr_reader :password
|
||||||
|
|
||||||
attr_accessor :password
|
validates :email, presence: true, uniqueness: true
|
||||||
before_save :encrypt_password
|
validates :password, confirmation: true
|
||||||
|
validate do |user|
|
||||||
validates_confirmation_of :password
|
unless user.password_hash.present? && user.password_salt.present?
|
||||||
validates_presence_of :password, :on => :create
|
user.errors.add :password, :blank
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def encrypt_password
|
def self.attributes_protected_by_default
|
||||||
if password.present?
|
super + %w(password_hash password_salt)
|
||||||
self.password_salt = BCrypt::Engine.generate_salt
|
|
||||||
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_access_to?(supplier)
|
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
|
end
|
||||||
|
|
||||||
def admin?
|
def admin?
|
||||||
!!admin
|
!!admin
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
= f.input :email, required: true
|
= f.input :email, required: true
|
||||||
= f.input :password, required: true
|
= f.input :password, required: true
|
||||||
= f.input :password_confirmation, required: true
|
= f.input :password_confirmation, required: true
|
||||||
|
= f.input :admin, required: true
|
||||||
|
|
||||||
.form-actions
|
.form-actions
|
||||||
= f.submit class: 'btn'
|
= f.submit class: 'btn'
|
||||||
|
|
|
@ -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
|
|
9
config/database.yml.SAMPLE
Normal file
9
config/database.yml.SAMPLE
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
development:
|
||||||
|
adapter: mysql2
|
||||||
|
encoding: utf8
|
||||||
|
reconnect: false
|
||||||
|
database: development
|
||||||
|
pool: 5
|
||||||
|
username: root
|
||||||
|
password: secret
|
||||||
|
host: mysql
|
|
@ -1,6 +1,4 @@
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
get 'users/new'
|
|
||||||
get 'users/show'
|
|
||||||
get 'log_in' => 'sessions#new', :as => :log_in
|
get 'log_in' => 'sessions#new', :as => :log_in
|
||||||
match 'log_out' => 'sessions#destroy', :as => :log_out, :via => [:get, :post]
|
match 'log_out' => 'sessions#destroy', :as => :log_out, :via => [:get, :post]
|
||||||
resources :sessions, :only => [:new, :create, :destroy]
|
resources :sessions, :only => [:new, :create, :destroy]
|
||||||
|
@ -18,8 +16,4 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :users
|
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
|
end
|
||||||
|
|
5
db/migrate/20211219074758_index_users_by_unique_email.rb
Normal file
5
db/migrate/20211219074758_index_users_by_unique_email.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class IndexUsersByUniqueEmail < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_index :users, :email, unique: true
|
||||||
|
end
|
||||||
|
end
|
119
db/schema.rb
generated
119
db/schema.rb
generated
|
@ -1,85 +1,82 @@
|
||||||
# encoding: UTF-8
|
|
||||||
# This file is auto-generated from the current state of the database. Instead
|
# 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
|
# of editing this file, please use the migrations feature of Active Record to
|
||||||
# incrementally modify your database, and then regenerate this schema definition.
|
# incrementally modify your database, and then regenerate this schema definition.
|
||||||
#
|
#
|
||||||
# Note that this schema.rb definition is the authoritative source for your
|
# This file is the source Rails uses to define your schema when running `bin/rails
|
||||||
# database schema. If you need to create the application database on another
|
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
||||||
# system, you should be using db:schema:load, not running all the migrations
|
# be faster and is potentially less error prone than running all of your
|
||||||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
# migrations from scratch. Old migrations may fail to apply correctly if those
|
||||||
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
# 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: 2021_12_19_074758) do
|
||||||
|
|
||||||
create_table "articles", :force => true do |t|
|
create_table "articles", charset: "utf8", force: :cascade do |t|
|
||||||
t.string "name", :null => false
|
t.string "name", null: false
|
||||||
t.integer "supplier_id", :null => false
|
t.integer "supplier_id", null: false
|
||||||
t.string "number"
|
t.string "number"
|
||||||
t.string "note"
|
t.string "note"
|
||||||
t.string "manufacturer"
|
t.string "manufacturer"
|
||||||
t.string "origin"
|
t.string "origin"
|
||||||
t.string "unit"
|
t.string "unit"
|
||||||
t.decimal "price", :precision => 8, :scale => 2, :default => 0.0, :null => false
|
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 "tax", precision: 3, scale: 1, default: "7.0", null: false
|
||||||
t.decimal "deposit", :precision => 8, :scale => 2, :default => 0.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 "unit_quantity", precision: 4, scale: 1, default: "1.0", null: false
|
||||||
t.decimal "scale_quantity", :precision => 4, :scale => 2
|
t.decimal "scale_quantity", precision: 4, scale: 2
|
||||||
t.decimal "scale_price", :precision => 8, :scale => 2
|
t.decimal "scale_price", precision: 8, scale: 2
|
||||||
t.datetime "created_on"
|
t.datetime "created_on"
|
||||||
t.datetime "updated_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
|
end
|
||||||
|
|
||||||
add_index "articles", ["name"], :name => "index_articles_on_name"
|
create_table "suppliers", charset: "utf8", force: :cascade do |t|
|
||||||
add_index "articles", ["number", "supplier_id"], :name => "index_articles_on_number_and_supplier_id", :unique => true
|
t.string "name", null: false
|
||||||
|
t.string "address", null: false
|
||||||
create_table "suppliers", :force => true do |t|
|
t.string "phone", null: false
|
||||||
t.string "name", :null => false
|
t.string "phone2"
|
||||||
t.string "address", :null => false
|
t.string "fax"
|
||||||
t.string "phone", :null => false
|
t.string "email"
|
||||||
t.string "phone2"
|
t.string "url"
|
||||||
t.string "fax"
|
t.string "delivery_days"
|
||||||
t.string "email"
|
t.string "note"
|
||||||
t.string "url"
|
|
||||||
t.string "delivery_days"
|
|
||||||
t.string "note"
|
|
||||||
t.datetime "created_on"
|
t.datetime "created_on"
|
||||||
t.datetime "updated_on"
|
t.datetime "updated_on"
|
||||||
t.boolean "ftp_sync", :default => false
|
t.boolean "ftp_sync", default: false
|
||||||
t.string "ftp_host"
|
t.string "ftp_host"
|
||||||
t.string "ftp_user"
|
t.string "ftp_user"
|
||||||
t.string "ftp_password"
|
t.string "ftp_password"
|
||||||
t.string "ftp_type", :default => "bnn", :null => false
|
t.string "ftp_type", default: "bnn", null: false
|
||||||
t.string "ftp_regexp", :default => "^([.]/)?PL"
|
t.string "ftp_regexp", default: "^([.]/)?PL"
|
||||||
t.boolean "mail_sync"
|
t.boolean "mail_sync"
|
||||||
t.string "mail_from"
|
t.string "mail_from"
|
||||||
t.string "mail_subject"
|
t.string "mail_subject"
|
||||||
t.string "mail_type"
|
t.string "mail_type"
|
||||||
t.string "salt", :null => false
|
t.string "salt", null: false
|
||||||
|
t.index ["name"], name: "index_suppliers_on_name", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "suppliers", ["name"], :name => "index_suppliers_on_name", :unique => true
|
create_table "user_accesses", charset: "utf8", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
create_table "user_accesses", :force => true do |t|
|
t.integer "supplier_id"
|
||||||
t.integer "user_id"
|
|
||||||
t.integer "supplier_id"
|
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_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
|
end
|
||||||
|
|
||||||
add_index "user_accesses", ["supplier_id"], :name => "index_user_accesses_on_supplier_id"
|
create_table "users", charset: "utf8", force: :cascade do |t|
|
||||||
add_index "user_accesses", ["user_id", "supplier_id"], :name => "index_user_accesses_on_user_id_and_supplier_id"
|
t.string "email"
|
||||||
add_index "user_accesses", ["user_id"], :name => "index_user_accesses_on_user_id"
|
t.string "password_hash"
|
||||||
|
t.string "password_salt"
|
||||||
create_table "users", :force => true do |t|
|
|
||||||
t.string "email"
|
|
||||||
t.string "password_hash"
|
|
||||||
t.string "password_salt"
|
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.boolean "admin", :default => false
|
t.boolean "admin", default: false
|
||||||
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue