erp_tech_svcs 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|