erp_tech_svcs 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/GPL-3-LICENSE +674 -0
- data/README.rdoc +2 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/erp_tech_svcs/application.js +9 -0
- data/app/assets/stylesheets/erp_tech_svcs/application.css +7 -0
- data/app/controllers/erp_tech_svcs/session_controller.rb +19 -0
- data/app/controllers/erp_tech_svcs/user_controller.rb +40 -0
- data/app/helpers/erp_tech_svcs/application_helper.rb +4 -0
- data/app/mailers/user_mailer.rb +16 -0
- data/app/models/audit_log.rb +60 -0
- data/app/models/audit_log_item.rb +4 -0
- data/app/models/audit_log_item_type.rb +6 -0
- data/app/models/audit_log_type.rb +24 -0
- data/app/models/capability.rb +8 -0
- data/app/models/capability_type.rb +3 -0
- data/app/models/capable_model.rb +4 -0
- data/app/models/encryption_key.rb +9 -0
- data/app/models/extensions/contact_purpose.rb +3 -0
- data/app/models/extensions/contact_type.rb +3 -0
- data/app/models/extensions/note.rb +6 -0
- data/app/models/extensions/note_type.rb +3 -0
- data/app/models/extensions/party.rb +3 -0
- data/app/models/extensions/relationship_type.rb +3 -0
- data/app/models/extensions/role_type.rb +3 -0
- data/app/models/file_asset.rb +178 -0
- data/app/models/role.rb +17 -0
- data/app/models/secured_model.rb +13 -0
- data/app/models/user.rb +33 -0
- data/app/views/layouts/application.html.erb +14 -0
- data/app/views/layouts/erp_tech_svcs/application.html.erb +14 -0
- data/app/views/user_mailer/activation_needed_email.html.erb +14 -0
- data/app/views/user_mailer/reset_password_email.html.erb +14 -0
- data/config/initializers/erp_tech_svcs.rb +7 -0
- data/config/initializers/file_support.rb +1 -0
- data/config/initializers/pdfkit.rb +18 -0
- data/config/initializers/sorcery.rb +199 -0
- data/config/routes.rb +9 -0
- data/db/data_migrations/20110802200222_schedule_delete_expired_sessions_job.rb +15 -0
- data/db/data_migrations/20111111144706_setup_audit_log_types.rb +21 -0
- data/db/migrate/20080805000010_base_tech_services.rb +247 -0
- data/db/migrate/20111109161549_add_capabilites.rb +56 -0
- data/db/migrate/upgrade/20111109161550_update_roles.rb +33 -0
- data/db/migrate/upgrade/20111109161551_update_user.rb +88 -0
- data/lib/erp_tech_svcs/application_installer.rb +102 -0
- data/lib/erp_tech_svcs/config.rb +27 -0
- data/lib/erp_tech_svcs/engine.rb +14 -0
- data/lib/erp_tech_svcs/extensions/active_record/acts_as_versioned.rb +494 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_capabilities.rb +139 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_file_assets.rb +40 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_roles.rb +126 -0
- data/lib/erp_tech_svcs/extensions.rb +5 -0
- data/lib/erp_tech_svcs/file_support/aws_s3_patch.rb +3 -0
- data/lib/erp_tech_svcs/file_support/base.rb +30 -0
- data/lib/erp_tech_svcs/file_support/file_manipulator.rb +37 -0
- data/lib/erp_tech_svcs/file_support/file_system_manager.rb +167 -0
- data/lib/erp_tech_svcs/file_support/manager.rb +147 -0
- data/lib/erp_tech_svcs/file_support/paperclip_patch.rb +28 -0
- data/lib/erp_tech_svcs/file_support/railties/s3_resolver.rb +79 -0
- data/lib/erp_tech_svcs/file_support/s3_manager.rb +211 -0
- data/lib/erp_tech_svcs/file_support.rb +10 -0
- data/lib/erp_tech_svcs/sessions/delete_expired_sessions_job.rb +40 -0
- data/lib/erp_tech_svcs/sessions/delete_expired_sessions_service.rb +15 -0
- data/lib/erp_tech_svcs/utils/attachment_fu_patch.rb +15 -0
- data/lib/erp_tech_svcs/utils/compass_access_negotiator.rb +57 -0
- data/lib/erp_tech_svcs/utils/compass_logger.rb +94 -0
- data/lib/erp_tech_svcs/utils/compass_pdf.rb +72 -0
- data/lib/erp_tech_svcs/utils/default_nested_set_methods.rb +33 -0
- data/lib/erp_tech_svcs/utils/pdf_processor.rb +106 -0
- data/lib/erp_tech_svcs/version.rb +3 -0
- data/lib/erp_tech_svcs.rb +20 -0
- data/lib/tasks/erp_tech_svcs_tasks.rake +42 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +43 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +8 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/spec.rb +27 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/schema.rb +571 -0
- data/spec/dummy/db/spec.sqlite3 +0 -0
- data/spec/dummy/log/spec.log +2862 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/capability_type.rb +5 -0
- data/spec/factories/role.rb +5 -0
- data/spec/factories/users.rb +9 -0
- data/spec/lib/erp_tech_svcs/extensions/active_record/has_roles_spec.rb +68 -0
- data/spec/models/audit_log_spec.rb +48 -0
- data/spec/models/audit_log_type_spec.rb +9 -0
- data/spec/models/role_spec.rb +17 -0
- data/spec/models/user_spec.rb +27 -0
- data/spec/spec_helper.rb +61 -0
- metadata +273 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'rdoc/task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require 'rdoc/rdoc'
|
|
11
|
+
require 'rake/rdoctask'
|
|
12
|
+
RDoc::Task = Rake::RDocTask
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
+
rdoc.title = 'ErpTechSvcs'
|
|
18
|
+
rdoc.options << '--line-numbers'
|
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
|
24
|
+
load 'rails/tasks/engine.rake'
|
|
25
|
+
|
|
26
|
+
Bundler::GemHelper.install_tasks
|
|
27
|
+
|
|
28
|
+
require "rspec/core/rake_task"
|
|
29
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
30
|
+
task :default => :spec
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into including all the files listed below.
|
|
2
|
+
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
|
3
|
+
// be included in the compiled file accessible from http://example.com/assets/application.js
|
|
4
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
5
|
+
// the compiled file.
|
|
6
|
+
//
|
|
7
|
+
//= require jquery
|
|
8
|
+
//= require jquery_ujs
|
|
9
|
+
//= require_tree .
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
|
3
|
+
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
|
4
|
+
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
|
5
|
+
*= require_self
|
|
6
|
+
*= require_tree .
|
|
7
|
+
*/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module ErpTechSvcs
|
|
2
|
+
class SessionController < ActionController::Base
|
|
3
|
+
def create
|
|
4
|
+
if login(params[:login],params[:password])
|
|
5
|
+
request.xhr? ? (render :json => {:success => true}) : (redirect_to params[:login_to])
|
|
6
|
+
else
|
|
7
|
+
message = "Login failed. Try again"
|
|
8
|
+
flash[:notice] = message
|
|
9
|
+
request.xhr? ? (render :json => {:success => false, :errors => {:reason => message}}) : (render :text => message)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def destroy
|
|
14
|
+
logout
|
|
15
|
+
login_url = params[:login_url].blank? ? ErpTechSvcs::Config.login_url : params[:login_url]
|
|
16
|
+
redirect_to login_url, :notice => "You have successfully logged out."
|
|
17
|
+
end
|
|
18
|
+
end#SessionsController
|
|
19
|
+
end#ErpTechSvcs
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module ErpTechSvcs
|
|
2
|
+
class UserController < ActionController::Base
|
|
3
|
+
def activate
|
|
4
|
+
login_url = params[:login_url].blank? ? ErpTechSvcs::Config.login_url : params[:login_url]
|
|
5
|
+
if @user = User.load_from_activation_token(params[:activation_token])
|
|
6
|
+
@user.activate!
|
|
7
|
+
redirect_to login_url, :notice => 'User was successfully activated.'
|
|
8
|
+
else
|
|
9
|
+
redirect_to login_url, :notice => "Invalid activation token."
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def reset_password
|
|
14
|
+
begin
|
|
15
|
+
login_url = params[:login_url].blank? ? ErpTechSvcs::Config.login_url : params[:login_url]
|
|
16
|
+
if user = (User.find_by_email(params[:login]) || User.find_by_username(params[:login]))
|
|
17
|
+
new_password = Sorcery::Model::TemporaryToken.generate_random_token
|
|
18
|
+
user.password_confirmation = new_password
|
|
19
|
+
if user.change_password!(new_password)
|
|
20
|
+
user.add_instance_attribute(:login_url,login_url)
|
|
21
|
+
user.deliver_reset_password_instructions!
|
|
22
|
+
message = "Password has been reset. An email has been sent with further instructions to #{user.email}."
|
|
23
|
+
success = true
|
|
24
|
+
else
|
|
25
|
+
message = "Error re-setting password."
|
|
26
|
+
success = false
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
message = "Invalid email address."
|
|
30
|
+
success = false
|
|
31
|
+
end
|
|
32
|
+
render :json => {:success => success,:message => message}
|
|
33
|
+
rescue Exception=>ex
|
|
34
|
+
logger.error ex.message
|
|
35
|
+
logger.error ex.backtrace
|
|
36
|
+
render :json => {:success => false,:message => 'Error sending email.'}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end#UserController
|
|
40
|
+
end#ErpTechSvcs
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class UserMailer < ActionMailer::Base
|
|
2
|
+
default :from => ErpTechSvcs::Config.email_notifications_from
|
|
3
|
+
|
|
4
|
+
def activation_needed_email(user)
|
|
5
|
+
@user = user
|
|
6
|
+
@url = "#{ErpTechSvcs::Config.installation_domain}/users/activate/#{user.activation_token}"
|
|
7
|
+
@url << "?login_url=#{@user.instance_attributes[:login_url]}" unless @user.instance_attributes[:login_url].nil?
|
|
8
|
+
mail(:to => user.email, :subject => "An account has been created and needs activation")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def reset_password_email(user)
|
|
12
|
+
@user = user
|
|
13
|
+
@url = "#{ErpTechSvcs::Config.installation_domain}#{@user.instance_attributes[:login_url]}"
|
|
14
|
+
mail(:to => user.email, :subject => "Your password has been reset")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
class AuditLog < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
validates :party_id, :presence => {:message => 'Party cannot be blank'}
|
|
4
|
+
validates :description, :presence => {:message => 'Description cannot be blank'}
|
|
5
|
+
validates :audit_log_type, :presence => {:message => 'Audit Log Type cannot be blank'}
|
|
6
|
+
|
|
7
|
+
belongs_to :audit_log_type
|
|
8
|
+
has_many :audit_log_items
|
|
9
|
+
belongs_to :event_record, :polymorphic => true
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
def custom_application_log_message(party, msg)
|
|
13
|
+
self.create(
|
|
14
|
+
:party_id => party.id,
|
|
15
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','custom_message'),
|
|
16
|
+
:description => "#{party.description}: #{msg}"
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def party_logout(party)
|
|
21
|
+
self.create(
|
|
22
|
+
:party_id => party.id,
|
|
23
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','successful_logout'),
|
|
24
|
+
:description => "#{party.description} has logged out"
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def party_login(party)
|
|
29
|
+
self.create(
|
|
30
|
+
:party_id => party.id,
|
|
31
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','successful_login'),
|
|
32
|
+
:description => "#{party.description} has logged in"
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def party_access(party, url)
|
|
37
|
+
self.create(
|
|
38
|
+
:party_id => party.id,
|
|
39
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','accessed_area'),
|
|
40
|
+
:description => "#{party.description} has accessed area #{url}"
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def party_failed_access(party, url)
|
|
45
|
+
self.create(
|
|
46
|
+
:party_id => party.id,
|
|
47
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','accessed_area'),
|
|
48
|
+
:description => "#{party.description} has tried to access a restricted area #{url}"
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def party_session_timeout(party)
|
|
53
|
+
self.create(
|
|
54
|
+
:party_id => party.id,
|
|
55
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','session_timeout'),
|
|
56
|
+
:description => "#{party.description} session has expired"
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class AuditLogType < ActiveRecord::Base
|
|
2
|
+
acts_as_nested_set
|
|
3
|
+
include ErpTechSvcs::Utils::DefaultNestedSetMethods
|
|
4
|
+
acts_as_erp_type
|
|
5
|
+
has_many :audit_logs
|
|
6
|
+
belongs_to_erp_type :parent, :class_name => "AuditLogType"
|
|
7
|
+
|
|
8
|
+
# find by type Internal Identifier and subtype Internal Identifier
|
|
9
|
+
def self.find_by_type_and_subtype_iid(txn_type, txn_subtype)
|
|
10
|
+
result = nil
|
|
11
|
+
txn_type_recs = find_all_by_internal_identifier(txn_type.strip)
|
|
12
|
+
txn_type_recs.each do |txn_type_rec|
|
|
13
|
+
txn_subtype_rec = find_by_parent_id_and_internal_identifier(txn_type_rec.id, txn_subtype.strip)
|
|
14
|
+
result = txn_subtype_rec
|
|
15
|
+
unless txn_subtype_rec.nil?
|
|
16
|
+
result = txn_subtype_rec
|
|
17
|
+
break
|
|
18
|
+
end
|
|
19
|
+
end unless txn_type_recs.blank?
|
|
20
|
+
|
|
21
|
+
result
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
Paperclip.interpolates(:file_path){|data, style|
|
|
4
|
+
case ErpTechSvcs::FileSupport.options[:storage]
|
|
5
|
+
when :filesystem
|
|
6
|
+
File.join(Rails.root,'public',data.instance.directory,data.instance.name)
|
|
7
|
+
when :s3
|
|
8
|
+
File.join(data.instance.directory,data.instance.name)
|
|
9
|
+
end
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Paperclip.interpolates(:file_url){|data, style|File.join(data.instance.directory,data.instance.name)}
|
|
13
|
+
|
|
14
|
+
class FileAsset < ActiveRecord::Base
|
|
15
|
+
if respond_to?(:class_attribute)
|
|
16
|
+
class_attribute :file_type
|
|
17
|
+
class_attribute :valid_extensions
|
|
18
|
+
class_attribute :content_type
|
|
19
|
+
else
|
|
20
|
+
class_inheritable_accessor :file_type
|
|
21
|
+
class_inheritable_accessor :content_type
|
|
22
|
+
class_inheritable_writer :valid_extensions
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after_create :set_sti
|
|
26
|
+
after_save :set_data_file_name
|
|
27
|
+
|
|
28
|
+
belongs_to :file_asset_holder, :polymorphic => true
|
|
29
|
+
instantiates_with_sti
|
|
30
|
+
|
|
31
|
+
#paperclip
|
|
32
|
+
has_attached_file :data,
|
|
33
|
+
:storage => ErpTechSvcs::FileSupport.options[:storage],
|
|
34
|
+
:s3_credentials => "#{Rails.root}/config/s3.yml",
|
|
35
|
+
:path => ":file_path",
|
|
36
|
+
:url => ":file_url",
|
|
37
|
+
:validations => { :extension => lambda { |data, file| validate_extension(data, file) } }
|
|
38
|
+
|
|
39
|
+
before_post_process :set_content_type
|
|
40
|
+
|
|
41
|
+
validates_attachment_presence :data
|
|
42
|
+
validates_attachment_size :data, :less_than => Rails.application.config.erp_tech_svcs.max_file_size_in_mb.megabytes
|
|
43
|
+
|
|
44
|
+
validates :name, :presence => {:message => 'Name can not be blank'}
|
|
45
|
+
validates_uniqueness_of :name, :scope => [:directory]
|
|
46
|
+
validates_each :directory, :name do |record, attr, value|
|
|
47
|
+
record.errors.add attr, 'may not contain consequtive dots' if value =~ /\.\./
|
|
48
|
+
end
|
|
49
|
+
validates_format_of :name, :with => /^\w/
|
|
50
|
+
|
|
51
|
+
class << self
|
|
52
|
+
def acceptable?(name)
|
|
53
|
+
valid_extensions.include?(File.extname(name))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def type_for(name)
|
|
57
|
+
classes = all_subclasses.uniq
|
|
58
|
+
classes.detect{ |k| k.acceptable?(name) }.try(:name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def type_by_extension(extension)
|
|
62
|
+
all_subclasses.detect{ |k| k.valid_extensions.include?(extension) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def validate_extension(data, file)
|
|
66
|
+
if file.name && !file.class.valid_extensions.include?(::File.extname(file.name))
|
|
67
|
+
types = all_valid_extensions.map{ |type| type.gsub(/^\./, '') }.join(', ')
|
|
68
|
+
"#{file.name} is not a valid file type. Valid file types are #{types}."
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def valid_extensions
|
|
73
|
+
read_inheritable_attribute(:valid_extensions) || []
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def all_valid_extensions
|
|
77
|
+
all_subclasses.map { |k| k.valid_extensions }.flatten.uniq
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def split_path(path)
|
|
81
|
+
directory, name = ::File.split(path)
|
|
82
|
+
directory = nil if directory == '.'
|
|
83
|
+
[directory, name]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def initialize(attributes = {}, options)
|
|
88
|
+
attributes ||= {}
|
|
89
|
+
|
|
90
|
+
base_path = attributes.delete(:base_path)
|
|
91
|
+
@type, directory, name, data = attributes.values_at(:type, :directory, :name, :data)
|
|
92
|
+
base_path ||= data.original_filename if data.respond_to?(:original_filename)
|
|
93
|
+
|
|
94
|
+
directory, name = FileAsset.split_path(base_path) if base_path and name.blank?
|
|
95
|
+
directory.gsub!(File.join(Rails.root,'public'),'')
|
|
96
|
+
|
|
97
|
+
@type ||= FileAsset.type_for(name) if name
|
|
98
|
+
data = StringIO.new(data) if data.is_a?(String)
|
|
99
|
+
|
|
100
|
+
super attributes.merge(:directory => directory, :name => name, :data => data)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def basename
|
|
104
|
+
data_file_name.gsub(/\.#{extname}$/, "")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def extname
|
|
108
|
+
File.extname(self.data_file_name).gsub(/^\.+/, '')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def set_sti
|
|
112
|
+
update_attribute :type, @type
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def set_content_type
|
|
116
|
+
unless @type.nil?
|
|
117
|
+
klass = @type.constantize
|
|
118
|
+
content_type = klass == Image ? "image/#{self.extname.downcase}" : klass.content_type
|
|
119
|
+
self.data.instance_write(:content_type, content_type)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def set_data_file_name
|
|
124
|
+
update_attribute :data_file_name, name if data_file_name != name
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def move(new_parent_path)
|
|
128
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
|
129
|
+
file_support.save_move(File.join(self.directory,self.name), new_parent_path)
|
|
130
|
+
self.directory = new_parent_path
|
|
131
|
+
self.save
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
class Image < FileAsset
|
|
137
|
+
self.file_type = :image
|
|
138
|
+
self.valid_extensions = %w(.jpg .jpeg .gif .png .ico .PNG .JPEG .JPG)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class TextFile < FileAsset
|
|
142
|
+
self.file_type = :textfile
|
|
143
|
+
self.content_type = 'text/plain'
|
|
144
|
+
self.valid_extensions = %w(.txt .text)
|
|
145
|
+
|
|
146
|
+
def data=(data)
|
|
147
|
+
data = StringIO.new(data) if data.is_a?(String)
|
|
148
|
+
super
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def text
|
|
152
|
+
@text ||= ::File.read(path) rescue ''
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class Javascript < TextFile
|
|
157
|
+
self.file_type = :javascript
|
|
158
|
+
self.content_type = 'text/javascript'
|
|
159
|
+
self.valid_extensions = %w(.js)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
class Stylesheet < TextFile
|
|
163
|
+
self.file_type = :stylesheet
|
|
164
|
+
self.content_type = 'text/css'
|
|
165
|
+
self.valid_extensions = %w(.css)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
class Template < TextFile
|
|
169
|
+
self.file_type = :template
|
|
170
|
+
self.content_type = 'text/plain'
|
|
171
|
+
self.valid_extensions = %w(.erb .haml .liquid .builder)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
class HtmlFile < TextFile
|
|
175
|
+
self.file_type = :html
|
|
176
|
+
self.content_type = 'text/html'
|
|
177
|
+
self.valid_extensions = %w(.html)
|
|
178
|
+
end
|
data/app/models/role.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class Role < ActiveRecord::Base
|
|
2
|
+
acts_as_erp_type
|
|
3
|
+
|
|
4
|
+
has_and_belongs_to_many :secured_models
|
|
5
|
+
|
|
6
|
+
validates :internal_identifier, :presence => {:message => 'Internal identifier cannot be blank'}
|
|
7
|
+
validates :internal_identifier, :presence => {:message => 'Description cannot be blank'}
|
|
8
|
+
validates_length_of :internal_identifier, :within => 3..100
|
|
9
|
+
validates_uniqueness_of :internal_identifier, :case_sensitive => false
|
|
10
|
+
|
|
11
|
+
def to_xml(options = {})
|
|
12
|
+
default_only = []
|
|
13
|
+
options[:only] = (options[:only] || []) + default_only
|
|
14
|
+
super(options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class SecuredModel < ActiveRecord::Base
|
|
2
|
+
belongs_to :secured_record, :polymorphic => true
|
|
3
|
+
has_and_belongs_to_many :roles
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
def find_models_by_klass_and_role(model_klass, role)
|
|
7
|
+
role = Role.iid(role) if role.is_a? String
|
|
8
|
+
|
|
9
|
+
SecuredModel.joins(['join roles_secured_models on roles_secured_models.secured_model_id = secured_models.id']).where('secured_record_type = ? and role_id = ?',model_klass, role.id).collect(&:secured_record)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
data/app/models/user.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
class User < ActiveRecord::Base
|
|
2
|
+
has_roles
|
|
3
|
+
include ErpTechSvcs::Utils::CompassAccessNegotiator
|
|
4
|
+
|
|
5
|
+
belongs_to :party
|
|
6
|
+
|
|
7
|
+
attr_accessible :email, :password, :password_confirmation
|
|
8
|
+
authenticates_with_sorcery!
|
|
9
|
+
|
|
10
|
+
#password validations
|
|
11
|
+
validates_length_of :password, :minimum => 3, :message => "password must be at least 3 characters long", :if => :password
|
|
12
|
+
validates_confirmation_of :password, :message => "should match confirmation", :if => :password
|
|
13
|
+
|
|
14
|
+
#email validations
|
|
15
|
+
validates :email, :presence => {:message => 'Email cannot be blank'}
|
|
16
|
+
validates_uniqueness_of :email
|
|
17
|
+
validates_format_of :email, :with => /\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}\z/
|
|
18
|
+
|
|
19
|
+
#username validations
|
|
20
|
+
validates :email, :presence => {:message => 'Username cannot be blank'}
|
|
21
|
+
validates_uniqueness_of :username
|
|
22
|
+
|
|
23
|
+
#these two methods allow us to assign instance level attributes that are not persisted. These are used for mailers
|
|
24
|
+
def instance_attributes
|
|
25
|
+
@instance_attrs.nil? ? {} : @instance_attrs
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def add_instance_attribute(k,v)
|
|
29
|
+
@instance_attrs = {} if @instance_attrs.nil?
|
|
30
|
+
@instance_attrs[k] = v
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>ErpTechSvcs</title>
|
|
5
|
+
<%= stylesheet_link_tag "erp_tech_svcs/application" %>
|
|
6
|
+
<%= javascript_include_tag "erp_tech_svcs/application" %>
|
|
7
|
+
<%= csrf_meta_tags %>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
|
|
11
|
+
<%= yield %>
|
|
12
|
+
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>ErpTechSvcs</title>
|
|
5
|
+
<%= stylesheet_link_tag "erp_tech_svcs/application" %>
|
|
6
|
+
<%= javascript_include_tag "erp_tech_svcs/application" %>
|
|
7
|
+
<%= csrf_meta_tags %>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
|
|
11
|
+
<%= yield %>
|
|
12
|
+
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
|
5
|
+
</head>
|
|
6
|
+
<body>
|
|
7
|
+
<h1>Welcome <%= @user.username %></h1>
|
|
8
|
+
<p>
|
|
9
|
+
You have successfully registered, to activate your account follow this link: <a href="<%= @url %>"><%= @url %></a>.
|
|
10
|
+
</p>
|
|
11
|
+
<p>Your username is <%=@user.username%> and your temporary password is <%=@user.instance_attributes[:temp_password]%></p>
|
|
12
|
+
<p>Thanks for joining and have a great day!!</p>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
|
5
|
+
</head>
|
|
6
|
+
<body>
|
|
7
|
+
<h1>We have reset the password for, <%= @user.username %></h1>
|
|
8
|
+
<p>
|
|
9
|
+
The new password is <%= @user.password_confirmation %>.
|
|
10
|
+
To login and update your password follow this link: <a href="<%= @url %>"><%= @url %></a>.
|
|
11
|
+
</p>
|
|
12
|
+
<p>Thanks for being a member and have a great day!</p>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Rails.application.config.erp_tech_svcs.configure do |config|
|
|
2
|
+
config.installation_domain = 'localhost:3000'
|
|
3
|
+
config.login_url = '/erp_app/login'
|
|
4
|
+
config.email_notifications_from = 'notifications@noreply.com'
|
|
5
|
+
config.max_file_size_in_mb = 5
|
|
6
|
+
end
|
|
7
|
+
Rails.application.config.erp_tech_svcs.configure!
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ErpTechSvcs::FileSupport::S3Manager.setup_connection() if ErpTechSvcs::FileSupport.options[:storage] == :s3
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# config/initializers/pdfkit.rb
|
|
2
|
+
PDFKit.configure do |config|
|
|
3
|
+
if RUBY_PLATFORM =~ /(:?mswin|mingw)/
|
|
4
|
+
# set path to wkhtmltopdf on windows here
|
|
5
|
+
config.wkhtmltopdf = '/opt/local/bin/wkhtmltopdf'
|
|
6
|
+
else
|
|
7
|
+
config.wkhtmltopdf = '/opt/local/bin/wkhtmltopdf'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
config.default_options = {
|
|
11
|
+
:page_size => 'Letter',
|
|
12
|
+
:print_media_type => true,
|
|
13
|
+
:disable_smart_shrinking => true,
|
|
14
|
+
:dpi => 300,
|
|
15
|
+
:no_background => true
|
|
16
|
+
# :use_xserver => true
|
|
17
|
+
}
|
|
18
|
+
end
|