rapid 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +66 -0
- data/lib/rad/http_controller/acts_as/authenticated.rb +131 -0
- data/lib/rad/http_controller/acts_as/authenticated_master_domain.rb +119 -0
- data/lib/rad/http_controller/acts_as/authorized.rb +83 -0
- data/lib/rad/http_controller/acts_as/localized.rb +27 -0
- data/lib/rad/http_controller/acts_as/multitenant.rb +53 -0
- data/lib/rad/http_controller/helpers/service_mix_helper.rb +50 -0
- data/lib/rad/http_controller.rb +15 -0
- data/lib/rad/lib/text_utils.rb +334 -0
- data/lib/rad/locales/en.yml +80 -0
- data/lib/rad/locales/ru.yml +83 -0
- data/lib/rad/locales.rb +2 -0
- data/lib/rad/models/account.rb +88 -0
- data/lib/rad/models/default_permissions.yml +26 -0
- data/lib/rad/models/micelaneous.rb +1 -0
- data/lib/rad/models/role.rb +88 -0
- data/lib/rad/models/secure_token.rb +33 -0
- data/lib/rad/models/space.rb +184 -0
- data/lib/rad/models/user.rb +158 -0
- data/lib/rad/models.rb +41 -0
- data/lib/rad/mongo_mapper/acts_as/authenticated_by_open_id.rb +29 -0
- data/lib/rad/mongo_mapper/acts_as/authenticated_by_password.rb +120 -0
- data/lib/rad/mongo_mapper/acts_as/authorized.rb +197 -0
- data/lib/rad/mongo_mapper/acts_as/authorized_object.rb +171 -0
- data/lib/rad/mongo_mapper/multitenant.rb +34 -0
- data/lib/rad/mongo_mapper/rad_micelaneous.rb +43 -0
- data/lib/rad/mongo_mapper/space_keys.rb +62 -0
- data/lib/rad/mongo_mapper/text_processor.rb +47 -0
- data/lib/rad/mongo_mapper.rb +20 -0
- data/lib/rad/paperclip/callbacks.rb +40 -0
- data/lib/rad/paperclip/extensions.rb +64 -0
- data/lib/rad/paperclip/integration.rb +165 -0
- data/lib/rad/paperclip/mime.rb +5 -0
- data/lib/rad/paperclip/validations.rb +64 -0
- data/lib/rad/paperclip.rb +11 -0
- data/lib/rad/spec/controller.rb +51 -0
- data/lib/rad/spec/model/factories.rb +65 -0
- data/lib/rad/spec/model.rb +85 -0
- data/lib/rad/spec/rem_helper.rb +145 -0
- data/lib/rad/spec.rb +4 -0
- data/lib/rad/tasks/backup.rake +64 -0
- data/lib/rad/tasks/initialize.rake +35 -0
- data/lib/rad.rb +32 -0
- data/readme.md +3 -0
- data/spec/controller/authorization_spec.rb +146 -0
- data/spec/controller/helper.rb +14 -0
- data/spec/lib/helper.rb +7 -0
- data/spec/lib/text_utils_spec.rb +238 -0
- data/spec/models/authorization_spec.rb +93 -0
- data/spec/models/authorized_object_spec.rb +258 -0
- data/spec/models/file_audit_spec/100.txt +1 -0
- data/spec/models/file_audit_spec/302.txt +3 -0
- data/spec/models/file_audit_spec.rb +168 -0
- data/spec/models/helper.rb +11 -0
- data/spec/models/space_key_spec.rb +68 -0
- data/spec/models/user_spec.rb +80 -0
- data/spec/mongo_mapper/basic_spec.rb +41 -0
- data/spec/mongo_mapper/helper.rb +10 -0
- data/spec/spec.opts +4 -0
- metadata +138 -0
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
Dir.chdir File.dirname(__FILE__)
|
5
|
+
|
6
|
+
# Specs
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
10
|
+
t.spec_files = FileList["spec/**/*_spec.rb"].select{|f| f !~ /\/_/}
|
11
|
+
t.libs = ['lib'].collect{|f| "#{File.dirname __FILE__}/#{f}"}
|
12
|
+
end
|
13
|
+
|
14
|
+
# Gem
|
15
|
+
require 'rake/clean'
|
16
|
+
require 'rake/gempackagetask'
|
17
|
+
require 'fileutils'
|
18
|
+
|
19
|
+
spec = Gem::Specification.new do |s|
|
20
|
+
s.name = "rapid"
|
21
|
+
s.version = "0.0.1"
|
22
|
+
s.summary = "Rapid Application Development platform for Crystal framework"
|
23
|
+
s.description = "Rapid Application Development platform for Crystal framework"
|
24
|
+
s.author = "Alexey Petrushin"
|
25
|
+
# s.email = ""
|
26
|
+
s.homepage = "http://github.com/alexeypetrushin/rapid"
|
27
|
+
|
28
|
+
s.platform = Gem::Platform::RUBY
|
29
|
+
s.has_rdoc = true
|
30
|
+
# s.extra_rdoc_files = ["README.rdoc"]
|
31
|
+
|
32
|
+
# s.files = (%w{rakefile readme.md .gitignore} + Dir.glob("{app,lib,spec,.git}/**/*"))
|
33
|
+
s.files = (['Rakefile', 'readme.md'] + Dir.glob("{lib,spec}/**/*"))
|
34
|
+
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
|
37
|
+
[
|
38
|
+
'crystal',
|
39
|
+
].each{|name| s.add_dependency(name)}
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
PACKAGE_DIR = "#{File.expand_path File.dirname(__FILE__)}/build"
|
44
|
+
|
45
|
+
Rake::GemPackageTask.new(spec) do |p|
|
46
|
+
package_dir = PACKAGE_DIR
|
47
|
+
# FileUtils.mkdir package_dir unless File.exist? package_dir
|
48
|
+
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
49
|
+
p.need_zip = true
|
50
|
+
p.package_dir = package_dir
|
51
|
+
end
|
52
|
+
|
53
|
+
# CLEAN.include [ 'pkg', '*.gem']
|
54
|
+
|
55
|
+
task :push do
|
56
|
+
dir = Dir.chdir PACKAGE_DIR do
|
57
|
+
gem_file = Dir.glob("rapid*.gem").first
|
58
|
+
system "gem push #{gem_file}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
task :clean do
|
63
|
+
system "rm -r #{PACKAGE_DIR}"
|
64
|
+
end
|
65
|
+
|
66
|
+
task :release => [:gem, :push, :clean]
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# require 'rack/auth/basic.rb'
|
2
|
+
|
3
|
+
module Crystal
|
4
|
+
module HttpController
|
5
|
+
module Authenticated
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def acts_as_authenticated
|
9
|
+
include Rad::Authenticated::InstanceMethods
|
10
|
+
|
11
|
+
# TODO2 what to do whith helper methods?
|
12
|
+
# helper_method :login_path, :logout_path, :signup_path, :user_path
|
13
|
+
|
14
|
+
before :prepare_current_user_for_slave_domain
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
protected
|
20
|
+
def prepare_current_user_for_slave_domain
|
21
|
+
unless check_and_execute_cas_command
|
22
|
+
user = login_from_basic_auth || login_from_session || login_as_anonymous
|
23
|
+
raise "You probably don't create Anonymous User!" if user.nil?
|
24
|
+
User.current = user
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
#
|
30
|
+
# Authentication Methods
|
31
|
+
#
|
32
|
+
def login_from_basic_auth
|
33
|
+
# TODO2
|
34
|
+
# authenticate_with_http_basic do |login, password|
|
35
|
+
# User.authenticate_by_password login, password unless login.blank? or password.blank?
|
36
|
+
# end
|
37
|
+
# username, password = workspace.request.credentials
|
38
|
+
# User.authenticate_by_password username, password unless username.blank? or password.blank?
|
39
|
+
end
|
40
|
+
|
41
|
+
def login_from_session
|
42
|
+
session = workspace.request.session
|
43
|
+
User.find_by_id session['user_id'] unless session['user_id'].blank?
|
44
|
+
end
|
45
|
+
|
46
|
+
def login_as_anonymous
|
47
|
+
workspace.request.session[:user_id] = User.anonymous.id.to_s
|
48
|
+
User.anonymous
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
#
|
53
|
+
# CAS Authentication
|
54
|
+
#
|
55
|
+
def check_and_execute_cas_command
|
56
|
+
return unless params.include?('cas_token') or params.include?('cas_logout')
|
57
|
+
|
58
|
+
session = workspace.request.session
|
59
|
+
if params.include?('cas_token')
|
60
|
+
token = !params[:cas_token].blank? && SecureToken.by_token(params[:cas_token])
|
61
|
+
clear_session!
|
62
|
+
if token and !token[:user_id].blank? and (user = User.first(:id => token[:user_id], :state => 'active'))
|
63
|
+
session[:user_id] = user.id.to_s
|
64
|
+
else
|
65
|
+
session[:user_id] = User.anonymous.id.to_s
|
66
|
+
flash[:sticky_info] = t(:cas_try_more)
|
67
|
+
end
|
68
|
+
elsif params.include? 'cas_logout'
|
69
|
+
clear_session!
|
70
|
+
login_as_anonymous
|
71
|
+
end
|
72
|
+
|
73
|
+
# redirect to remove CAS params
|
74
|
+
uri = Uri.parse request.url
|
75
|
+
values = uri.query_values || {}
|
76
|
+
values.delete 'cas_logout'
|
77
|
+
values.delete 'cas_token'
|
78
|
+
uri.query_values = values
|
79
|
+
|
80
|
+
redirect_to uri.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
#
|
85
|
+
# Helpers
|
86
|
+
#
|
87
|
+
%w{login logout signup}.each do |path|
|
88
|
+
define_method "#{path}_path" do |*args|
|
89
|
+
options = args.first || {}
|
90
|
+
options = {
|
91
|
+
:host => config.master_domain!,
|
92
|
+
:port => config.port(nil),
|
93
|
+
:l => I18n.locale
|
94
|
+
}.merge(options)
|
95
|
+
options[:_return_to] = request.url unless params.include? :_return_to
|
96
|
+
url_for "#{ServiceMix.relative_url_root}/#{path}", options
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def user_path user, options = {}
|
101
|
+
url_for_path "#{ServiceMix.relative_url_root}/users/#{user.to_param}", options
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
#
|
106
|
+
# Special
|
107
|
+
#
|
108
|
+
PRESERVE_SESSION_KEYS = %w{authenticity_token}
|
109
|
+
crystal.after :config do |config|
|
110
|
+
if config.session?
|
111
|
+
session_id = config.session!.key!
|
112
|
+
PRESERVE_SESSION_KEYS << session_id unless PRESERVE_SESSION_KEYS.include? session_id
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
def clear_session!
|
118
|
+
workspace.request.session
|
119
|
+
|
120
|
+
session[:dumb_key] # hack, need this to initialize session, othervise it's empty
|
121
|
+
to_delete = session.keys.select{|key| !PRESERVE_SESSION_KEYS.include?(key.to_s)}
|
122
|
+
to_delete.each{|key| session.delete key}
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
Crystal::HttpController.inherit Crystal::HttpController::Authenticated
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Crystal
|
2
|
+
module HttpController
|
3
|
+
module AuthenticatedMasterDomain
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def acts_as_authenticated_master_domain
|
7
|
+
include Crystal::HttpController::AuthenticatedMasterDomain::InstanceMethods
|
8
|
+
|
9
|
+
# TODO1 what to do with helper_methods?
|
10
|
+
# helper_method :login_path, :logout_path, :signup_path, :user_path
|
11
|
+
before :prepare_current_user_for_master_domain
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
include ::Crystal::HttpController::Authenticated::InstanceMethods
|
17
|
+
|
18
|
+
protected
|
19
|
+
def prepare_current_user_for_master_domain
|
20
|
+
user = login_from_basic_auth || login_from_session || login_from_cookie || login_as_anonymous
|
21
|
+
raise "You probably don't create Anonymous User!" if user.nil?
|
22
|
+
User.current = user
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# Authentication Methods
|
28
|
+
#
|
29
|
+
def login_from_cookie
|
30
|
+
session, cookies = workspace.request.session, workspace.request.cookies
|
31
|
+
|
32
|
+
token = !cookies[:auth_token].blank? && SecureToken.by_token(cookies[:auth_token])
|
33
|
+
if token and !token[:user_id].blank? and (user = User.first(:id => token[:user_id], :state => 'active'))
|
34
|
+
session[:user_id] = user.id.to_s
|
35
|
+
user
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
#
|
41
|
+
# CAS Authentication
|
42
|
+
#
|
43
|
+
|
44
|
+
# returns cas_token only for another domains
|
45
|
+
def return_to_path_with_cas_token
|
46
|
+
unless master_domain? params[:_return_to]
|
47
|
+
token = SecureToken.new
|
48
|
+
token.expires_at = 5.minutes.from_now
|
49
|
+
token[:type] = 'cas'
|
50
|
+
token[:user_id] = User.current.id.to_s
|
51
|
+
token.save!
|
52
|
+
|
53
|
+
return return_to_path(:cas_token => token.token)
|
54
|
+
end
|
55
|
+
|
56
|
+
return_to_path
|
57
|
+
end
|
58
|
+
|
59
|
+
def return_to_path_with_logout_cas_token
|
60
|
+
unless master_domain? params[:_return_to]
|
61
|
+
return_to_path(:cas_logout => 'true')
|
62
|
+
else
|
63
|
+
return_to_path
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def return_cas_token_if_authenticated
|
68
|
+
# TODO1 fix it, there's no redirect anymore
|
69
|
+
redirect_to return_to_path_with_cas_token unless User.current.anonymous?
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
#
|
74
|
+
# Special
|
75
|
+
#
|
76
|
+
def master_domain? uri
|
77
|
+
unless uri.blank?
|
78
|
+
uri = Uri.parse(uri)
|
79
|
+
|
80
|
+
if !uri.host.blank? and uri.normalized_host != SETTING.master_domain!
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_current_user_with_updating_session user
|
88
|
+
session, cookies = workspace.request.session, workspace.request.cookies
|
89
|
+
current_user = User.current
|
90
|
+
user.must_not == current_user
|
91
|
+
|
92
|
+
# Clear
|
93
|
+
clear_session!
|
94
|
+
unless current_user.anonymous?
|
95
|
+
SecureToken.delete_all :user_id => current_user.id.to_s
|
96
|
+
cookies.delete :auth_token
|
97
|
+
end
|
98
|
+
|
99
|
+
# Set session and cookie token
|
100
|
+
session[:user_id] = user.id.to_s
|
101
|
+
unless user.anonymous?
|
102
|
+
token = SecureToken.new
|
103
|
+
token[:user_id] = user.id.to_s
|
104
|
+
token[:type] = 'cookie_auth'
|
105
|
+
token.expires_at = 2.weeks.from_now
|
106
|
+
token.save!
|
107
|
+
|
108
|
+
cookies[:auth_token] = {:value => token.token, :expires => token.expires_at}
|
109
|
+
end
|
110
|
+
|
111
|
+
User.current = user
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
Crystal::HttpController.inherit Crystal::HttpController::AuthenticatedMasterDomain
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Crystal
|
2
|
+
module HttpController
|
3
|
+
module Authorized
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def acts_as_authorized
|
7
|
+
include Crystal::HttpController::Authorized::InstanceMethods
|
8
|
+
extend Crystal::HttpController::Authorized::SingletonMethods
|
9
|
+
|
10
|
+
# TODO1 uncomment thouse helper methods
|
11
|
+
# helper_method :can?, :owner?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module SingletonMethods
|
16
|
+
def require_permission operation, *args, &object_proc
|
17
|
+
operation = operation.must_be.a([String, Symbol]).to_s
|
18
|
+
# operation.should! :be_in, Space.permissions
|
19
|
+
|
20
|
+
options = args.extract_options!
|
21
|
+
# object_proc = args.size > 0 ? args.first : lambda{}
|
22
|
+
object_proc ||= lambda{}
|
23
|
+
|
24
|
+
method = "require_permission_#{operation}"
|
25
|
+
define_method method do
|
26
|
+
require_permission operation, instance_eval(&object_proc)
|
27
|
+
end
|
28
|
+
before method, options
|
29
|
+
end
|
30
|
+
# alias_method :require_permission_to, :require_permission
|
31
|
+
end
|
32
|
+
|
33
|
+
module InstanceMethods
|
34
|
+
protected
|
35
|
+
def can? *args
|
36
|
+
User.current.can? *args
|
37
|
+
end
|
38
|
+
|
39
|
+
def owner? *args
|
40
|
+
User.current.owner? *args
|
41
|
+
end
|
42
|
+
|
43
|
+
def login_required
|
44
|
+
access_denied! unless User.current.registered?
|
45
|
+
end
|
46
|
+
|
47
|
+
def login_not_required
|
48
|
+
raise_user_error t(:login_not_required) if User.current.registered?
|
49
|
+
end
|
50
|
+
|
51
|
+
def require_permission operation, object = nil
|
52
|
+
operation = operation.must_be.a([String, Symbol]).to_s
|
53
|
+
# operation.should! :be_in, Space.permissions
|
54
|
+
|
55
|
+
unless User.current.can? operation, object
|
56
|
+
crystal.logger.warn "Access denied, #{User.current.name} hasn't rights to #{operation}!"
|
57
|
+
access_denied!
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def access_denied!
|
62
|
+
raise_user_error t(:access_denied)
|
63
|
+
end
|
64
|
+
|
65
|
+
# def access_denied
|
66
|
+
# respond_to do |format|
|
67
|
+
# format.html do
|
68
|
+
# flash[:info] = t(:login_required)
|
69
|
+
# session[:_return_to] = request.request_uri
|
70
|
+
# redirect_to new_session_path
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# format.any(:json, :xml) do
|
74
|
+
# request_http_basic_authentication 'Web Password'
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
# end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
Crystal::HttpController.inherit Crystal::HttpController::Authorized
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Crystal
|
2
|
+
module HttpController
|
3
|
+
module Localized
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def acts_as_localized
|
7
|
+
include Crystal::HttpController::Localized::InstanceMethods
|
8
|
+
before :prepare_locale
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
protected
|
14
|
+
def prepare_locale
|
15
|
+
default_language = (Space.current? ? Space.current.language : nil) || config.default_language('en')
|
16
|
+
I18n.locale = params[:l] || default_language
|
17
|
+
|
18
|
+
# Delete l from params if language is the same as default
|
19
|
+
params.delete 'l' if params[:l] == default_language
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Crystal::HttpController.inherit Crystal::HttpController::Localized
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Crystal
|
2
|
+
module HttpController
|
3
|
+
module Multitenant
|
4
|
+
|
5
|
+
module InstanceMethods
|
6
|
+
protected
|
7
|
+
def select_account_and_space
|
8
|
+
begin
|
9
|
+
# preparing Account
|
10
|
+
subdomains = request.subdomains.select{|n| n != 'www'}
|
11
|
+
subdomain = subdomains.last
|
12
|
+
pure_domain = request.domain.sub(/\A#{subdomains.join(".")}\./, "")
|
13
|
+
|
14
|
+
domain = subdomain.blank? ? pure_domain : "#{subdomain}.#{pure_domain}"
|
15
|
+
|
16
|
+
Account.current = Account.first :conditions => {:domains => domain}
|
17
|
+
unless Account.current?
|
18
|
+
msg = "No Account registered for the '#{pure_domain}' Domain"
|
19
|
+
logger.debug msg
|
20
|
+
raise msg
|
21
|
+
end
|
22
|
+
|
23
|
+
# preparing Space
|
24
|
+
space_name = params[:s] || 'default'
|
25
|
+
Space.current = Account.current.spaces.first :name => space_name
|
26
|
+
|
27
|
+
unless Space.current?
|
28
|
+
msg = "No '#{space_name}' Space for '#{Account.current.name}' Account"
|
29
|
+
logger.debug msg
|
30
|
+
raise msg
|
31
|
+
end
|
32
|
+
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
Account.current = nil
|
36
|
+
Space.current = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
def acts_as_multitenant
|
44
|
+
include Rad::Multitenant::InstanceMethods
|
45
|
+
|
46
|
+
around :select_account_and_space
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Crystal::HttpController.inherit Crystal::HttpController::Multitenant
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ServiceMixHelper
|
2
|
+
|
3
|
+
# [
|
4
|
+
# ['BOS-Tec', '/'],
|
5
|
+
# ['Lab', lab_path]
|
6
|
+
# ]
|
7
|
+
#
|
8
|
+
def logo
|
9
|
+
return [] if @logo.blank?
|
10
|
+
logo = @logo.is_a?(Array) ? @logo : [@logo]
|
11
|
+
logo.size.must_be.in 1..2
|
12
|
+
|
13
|
+
# Delete default space name if there is
|
14
|
+
logo = logo.select do |item|
|
15
|
+
if item.is_a?(Array)
|
16
|
+
!Space.default?(item[0])
|
17
|
+
else
|
18
|
+
!Space.default?(item)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
logo.collect{|item| item.is_a?(Array) ? link_to(item.first, item.last) : item}
|
23
|
+
end
|
24
|
+
|
25
|
+
# # [
|
26
|
+
# # ['Users', user_path],
|
27
|
+
# # ['Roles']
|
28
|
+
# # ]
|
29
|
+
# #
|
30
|
+
# def breadcrumb
|
31
|
+
# Array(@breadcrumb)
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
|
35
|
+
# def visibility_selector_for object
|
36
|
+
# object.should_not! :be_nil
|
37
|
+
# object.should! :be_a, MongoMapper::Acts::AuthorizedObject
|
38
|
+
# field_name = "#{object.class.model_name.underscore}[visibility_as_string]"
|
39
|
+
# html = ""
|
40
|
+
# Role::VISIBILITY_ROLES.each do |role|
|
41
|
+
# checked = role == object.visibility_as_string
|
42
|
+
# html += radio_button_tag field_name, role, checked
|
43
|
+
# html += label_tag "#{field_name}_#{role}", t("#{role}_role")
|
44
|
+
# html += "\n"
|
45
|
+
# end
|
46
|
+
# html
|
47
|
+
# end
|
48
|
+
end
|
49
|
+
|
50
|
+
Crystal::HttpController.helper ServiceMixHelper
|
@@ -0,0 +1,15 @@
|
|
1
|
+
%w(
|
2
|
+
authenticated
|
3
|
+
authenticated_master_domain
|
4
|
+
authorized
|
5
|
+
localized
|
6
|
+
multitenant
|
7
|
+
).each{|n| require "rad/http_controller/acts_as/#{n}"}
|
8
|
+
|
9
|
+
require 'rad/http_controller/helpers/service_mix_helper'
|
10
|
+
|
11
|
+
require 'rad/locales'
|
12
|
+
|
13
|
+
Crystal::Config::DEFAULTS.merge!({
|
14
|
+
:master_domain => "localhost",
|
15
|
+
}.stringify_keys)
|