ixtlan 0.2.4 → 0.3.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.
Files changed (87) hide show
  1. data/History.txt +49 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Manifest.txt +73 -48
  4. data/Rakefile +1 -1
  5. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/gwt_ixtlan_datamapper_rspec_scaffold_generator.rb +3 -3
  6. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/templates/AbstractApplicationResourceTestGwt.java +1 -1
  7. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/templates/Fields.java +1 -1
  8. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/templates/Model.java +2 -2
  9. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/templates/ModelFactory.java +2 -2
  10. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/templates/Screen.java +2 -2
  11. data/generators/gwt_ixtlan_datamapper_rspec_scaffold/templates/TestGwt.java +2 -2
  12. data/generators/ixtlan_datamapper_rspec_model/ixtlan_datamapper_rspec_model_generator.rb +1 -1
  13. data/generators/ixtlan_datamapper_rspec_scaffold/ixtlan_datamapper_rspec_scaffold_generator.rb +4 -4
  14. data/generators/ixtlan_datamapper_rspec_scaffold/templates/guard.rb +7 -7
  15. data/generators/ixtlan_datamapper_rspec_scaffold/templates/i18n.rb +1 -1
  16. data/generators/ixtlan_datamapper_rspec_scaffold/templates/layout.html.erb +20 -0
  17. data/ixtlan_rails_templates.rb +537 -0
  18. data/lib/ixtlan/audit_config.rb +5 -5
  19. data/lib/ixtlan/child_path.rb +2 -2
  20. data/lib/ixtlan/cms_script.rb +4 -4
  21. data/lib/ixtlan/controllers/authentications_controller.rb +7 -2
  22. data/lib/ixtlan/controllers/configurations_controller.rb +15 -6
  23. data/lib/ixtlan/controllers/domains_controller.rb +99 -0
  24. data/lib/ixtlan/controllers/groups_controller.rb +105 -0
  25. data/lib/ixtlan/controllers/locales_controller.rb +99 -0
  26. data/lib/ixtlan/controllers/permissions_controller.rb +5 -0
  27. data/lib/ixtlan/controllers/phrases_controller.rb +26 -22
  28. data/lib/ixtlan/controllers/search_query.rb +24 -0
  29. data/lib/ixtlan/controllers/texts_controller.rb +5 -5
  30. data/lib/ixtlan/controllers/users_controller.rb +117 -0
  31. data/lib/ixtlan/controllers/word_bundles_controller.rb +13 -8
  32. data/lib/ixtlan/digest.rb +3 -3
  33. data/lib/ixtlan/guard.rb +11 -12
  34. data/lib/ixtlan/logger_config.rb +11 -11
  35. data/lib/ixtlan/mailer/error_notification.erb +1 -0
  36. data/lib/ixtlan/mailer/password.erb +1 -0
  37. data/lib/ixtlan/mailer.rb +27 -0
  38. data/lib/ixtlan/models/authentication.rb +9 -6
  39. data/lib/ixtlan/models/configuration.rb +21 -37
  40. data/lib/ixtlan/models/configuration_locale.rb +3 -3
  41. data/lib/ixtlan/models/domain.rb +44 -0
  42. data/lib/ixtlan/models/domain_group_user.rb +22 -0
  43. data/lib/ixtlan/models/group.rb +82 -16
  44. data/lib/ixtlan/models/group_locale_user.rb +4 -4
  45. data/lib/ixtlan/models/group_user.rb +7 -7
  46. data/lib/ixtlan/models/i18n_text.rb +26 -26
  47. data/lib/ixtlan/models/locale.rb +17 -5
  48. data/lib/ixtlan/models/permission.rb +3 -2
  49. data/lib/ixtlan/models/phrase.rb +15 -15
  50. data/lib/ixtlan/models/role.rb +5 -5
  51. data/lib/ixtlan/models/translation.rb +9 -9
  52. data/lib/ixtlan/models/update_children.rb +74 -0
  53. data/lib/ixtlan/models/user.rb +108 -16
  54. data/lib/ixtlan/models/word.rb +2 -1
  55. data/lib/ixtlan/models.rb +1 -0
  56. data/lib/ixtlan/modified_by.rb +9 -7
  57. data/lib/ixtlan/monkey_patches.rb +5 -5
  58. data/lib/ixtlan/optimistic_persistence.rb +2 -2
  59. data/lib/ixtlan/optimistic_persistence_module.rb +3 -3
  60. data/lib/ixtlan/optimistic_persistence_validation.rb +2 -2
  61. data/lib/ixtlan/passwords.rb +15 -13
  62. data/lib/ixtlan/rails/error_handling.rb +41 -40
  63. data/lib/ixtlan/rails/guard.rb +0 -1
  64. data/lib/ixtlan/rails/migrations.rb +75 -0
  65. data/lib/ixtlan/rails/session_timeout.rb +16 -14
  66. data/lib/ixtlan/rails/timestamps_modified_by_filter.rb +1 -1
  67. data/lib/ixtlan/rails/unrestful_authentication.rb +4 -4
  68. data/lib/ixtlan/rolling_file.rb +3 -3
  69. data/lib/ixtlan/session.rb +4 -3
  70. data/lib/ixtlan/user_logger.rb +13 -9
  71. data/lib/ixtlan/version.rb +1 -1
  72. data/spec/authentication_spec.rb +1 -1
  73. data/spec/guard_spec.rb +4 -4
  74. data/spec/guards/samples.rb +7 -7
  75. data/spec/modified_by_spec.rb +82 -0
  76. data/spec/optimistic_persistence_spec.rb +58 -0
  77. data/spec/phrase_spec.rb +119 -0
  78. data/spec/session_timeout_spec.rb +59 -0
  79. data/spec/spec_helper.rb +6 -5
  80. data/spec/text_collection_spec.rb +88 -0
  81. data/spec/text_spec.rb +105 -0
  82. data/spec/unrestful_authentication_spec.rb +142 -0
  83. data/spec/user_logger_spec.rb +105 -0
  84. data/spec/user_spec.rb +249 -0
  85. data/whitespace.rb +31 -0
  86. metadata +76 -50
  87. data/lib/ixtlan/error_notifier/error_notification.rhtml +0 -1
@@ -1,3 +1,4 @@
1
+ require 'dm-serializer'
1
2
  module Ixtlan
2
3
  module Models
3
4
  class Locale
@@ -12,10 +13,13 @@ module Ixtlan
12
13
  ALL = "ALL"
13
14
  end
14
15
 
15
- property :code, String, :nullable => false , :format => /^[a-z][a-z](_[A-Z][A-Z])?$|^#{DEFAULT}$|^#{ALL}$/, :length => 7, :key => true
16
-
16
+ property :id, Serial
17
+ property :code, String, :required => true , :format => /^[a-z][a-z](_[A-Z][A-Z])?$|^#{DEFAULT}$|^#{ALL}$/, :length => 7, :unique_index => true
18
+
17
19
  timestamps :created_at
18
20
 
21
+ modified_by Models::USER, :created_by
22
+
19
23
  def parent
20
24
  c = attribute_get(:code)
21
25
  case c.size
@@ -29,17 +33,25 @@ module Ixtlan
29
33
  end
30
34
 
31
35
  def self.default
32
- get(DEFAULT) || create(:code => DEFAULT)
36
+ first(:code => DEFAULT)
33
37
  end
34
38
 
35
39
  def self.every
36
- get(ALL) || create(:code => ALL)
40
+ first(:code => ALL)
41
+ end
42
+
43
+ def self.first_or_get!(id_or_code)
44
+ first(:code => id_or_code) || get!(id_or_code)
45
+ end
46
+
47
+ def self.first_or_get(id_or_code)
48
+ first(:code => id_or_code) || get(id_or_code)
37
49
  end
38
50
 
39
51
  def hash
40
52
  attribute_get(:code).hash
41
53
  end
42
-
54
+
43
55
  alias :eql? :==
44
56
  def ==(other)
45
57
  attribute_get(:code).eql?(other.attribute_get(:code))
@@ -1,3 +1,4 @@
1
+ require 'dm-serializer'
1
2
  module Ixtlan
2
3
  module Models
3
4
  class Permission
@@ -15,9 +16,9 @@ module Ixtlan
15
16
  has n, :roles, :model => Models::ROLE
16
17
 
17
18
  if protected_instance_methods.find {|m| m == 'to_x'}.nil?
18
-
19
+
19
20
  protected
20
-
21
+
21
22
  alias :to_x :to_xml_document
22
23
  def to_xml_document(opts, doc = nil)
23
24
  opts.merge!({:methods => [:roles]})
@@ -1,3 +1,4 @@
1
+ require 'dm-serializer'
1
2
  module Ixtlan
2
3
  module Models
3
4
  class Phrase
@@ -9,25 +10,25 @@ module Ixtlan
9
10
 
10
11
  property :id, Serial
11
12
 
12
- property :code, String, :nullable => false, :length => 64
13
-
14
- property :text, String, :nullable => false, :length => 256
15
-
16
- property :current_text, String, :nullable => true, :length => 256
17
-
18
- property :updated_at, DateTime, :nullable => false, :auto_validation => false
19
-
13
+ property :code, String, :required => true, :length => 64
14
+
15
+ property :text, String, :required => true, :length => 256
16
+
17
+ property :current_text, String, :required => false, :length => 256
18
+
19
+ property :updated_at, DateTime, :required => true, :auto_validation => false
20
+
20
21
  belongs_to :updated_by, :model => Models::USER
21
-
22
+
22
23
  belongs_to :locale, :model => Models::LOCALE
23
-
24
- belongs_to :default_translation, :model => Models::TRANSLATION, :nullable => true
25
24
 
26
- belongs_to :parent_translation, :model => Models::TRANSLATION, :nullable => true
25
+ belongs_to :default_translation, :model => Models::TRANSLATION, :required => false
26
+
27
+ belongs_to :parent_translation, :model => Models::TRANSLATION, :required => false
27
28
 
28
29
  alias :to_x :to_xml_document
29
30
  def to_xml_document(opts = {}, doc = nil)
30
- opts.merge!({:exclude => [:id, :parent_translation_id, :default_translation_id, :locale_code], :element_name => 'phrase', :methods => [:default_translation, :parent_translation, :locale]})
31
+ opts.merge!({:exclude => [:id, :parent_translation_id, :default_translation_id, :locale_id], :element_name => 'phrase', :methods => [:default_translation, :parent_translation, :locale]})
31
32
  to_x(opts, doc)
32
33
  end
33
34
 
@@ -55,7 +56,7 @@ module Ixtlan
55
56
  ph = map[code]
56
57
  if(ph.nil?)
57
58
  map[code] = Phrase.new(:code => code, :text => trans.text, :current_text => trans.text, :locale => locale, :updated_at => trans.approved_at, :updated_by => trans.approved_by, :default_translation => trans)
58
- else
59
+ else
59
60
  ph.default_translation = trans
60
61
  end
61
62
  end
@@ -68,4 +69,3 @@ module Ixtlan
68
69
  end
69
70
  end
70
71
  end
71
-
@@ -1,14 +1,15 @@
1
+ require 'dm-serializer'
1
2
  module Ixtlan
2
3
  module Models
3
4
  class Role
4
5
 
5
6
  include DataMapper::Resource
6
-
7
+
7
8
  def self.default_storage_name
8
9
  "Role"
9
10
  end
10
11
 
11
- property :name, String, :nullable => false , :format => /^[a-zA-Z0-9\-_.]*$/, :length => 32, :key => true
12
+ property :name, String, :required => true , :format => /^[a-zA-Z0-9\-_.]*$/, :length => 32, :key => true
12
13
 
13
14
  def hash
14
15
  attribute_get(:name).hash
@@ -20,9 +21,9 @@ module Ixtlan
20
21
  end
21
22
 
22
23
  if protected_instance_methods.find {|m| m == 'to_x'}.nil?
23
-
24
+
24
25
  protected
25
-
26
+
26
27
  alias :to_x :to_xml_document
27
28
  def to_xml_document(opts, doc = nil)
28
29
  opts.merge!({:exclude => [:permission_resource,:permission_action]})
@@ -32,4 +33,3 @@ module Ixtlan
32
33
  end
33
34
  end
34
35
  end
35
-
@@ -1,3 +1,4 @@
1
+ require 'dm-serializer'
1
2
  module Ixtlan
2
3
  module Models
3
4
  class Translation
@@ -6,17 +7,17 @@ module Ixtlan
6
7
  def self.default_storage_name
7
8
  "Translation"
8
9
  end
9
-
10
+
10
11
  property :id, Serial
11
12
 
12
- property :text, String, :nullable => false, :length => 256
13
-
14
- property :previous_text, String, :nullable => true, :length => 256
15
-
16
- property :approved_at, DateTime, :nullable => false, :auto_validation => false
17
-
13
+ property :text, String, :required => true, :length => 256
14
+
15
+ property :previous_text, String, :required => false, :length => 256
16
+
17
+ property :approved_at, DateTime, :required => true, :auto_validation => false
18
+
18
19
  belongs_to :approved_by, :model => Models::USER
19
-
20
+
20
21
  def self.map_for(args = {})
21
22
  map = {}
22
23
  I18nText.latest_approved(args.dup).each do |text|
@@ -37,4 +38,3 @@ module Ixtlan
37
38
  end
38
39
  end
39
40
  end
40
-
@@ -0,0 +1,74 @@
1
+ module Ixtlan
2
+ module Models
3
+ module UpdateChildren
4
+
5
+ def update_children(new_children, old_children_sym)
6
+ # get the dm-core/collection and its model
7
+ old_children = send(old_children_sym)
8
+ model = old_children.model
9
+
10
+ # make sure we have an array
11
+ if new_children.is_a?(Array)
12
+ # ids of new children
13
+ new_ids = new_children.collect { |v| v.to_i }
14
+ else
15
+ new_children = if new_children.nil?
16
+ []
17
+ else
18
+ new_children[new_children.keys[0]]
19
+ end
20
+ new_children = [new_children] unless new_children.is_a? Array
21
+
22
+ # ids of new children
23
+ new_ids = new_children.collect { |v| v[:id].to_i }
24
+ end
25
+
26
+ # delete obsolete old children
27
+ old_children.select do |g|
28
+ !(new_ids.member? g.id)
29
+ end.each do |g|
30
+ old_children.delete(g)
31
+ end
32
+
33
+ # add missing new children
34
+ old_ids = old_children.collect { |g| g.id }
35
+ new_ids.each do |gid|
36
+ old_children << model.get!(gid) unless old_ids.member? gid
37
+ end
38
+ end
39
+
40
+ def update_restricted_children(new_children, old_children_sym, allowed_children)
41
+ # get the dm-core/collection and its model
42
+ old_children = send(old_children_sym)
43
+ model = old_children.model
44
+
45
+ # make sure we have an array
46
+ new_children = if new_children.nil?
47
+ []
48
+ else
49
+ new_children[new_children.keys[0]]
50
+ end
51
+ new_children = [new_children] unless new_children.is_a? Array
52
+
53
+ # ids of new children
54
+ new_ids = new_children.collect { |v| v[:id].to_i }
55
+ # ids of allowed children
56
+ allowed_ids = allowed_children.collect { |g| g.id }
57
+
58
+ # delete obsolete and allowed old children
59
+ set = old_children.select do |g|
60
+ !(new_ids.member? g.id) && (allowed_ids.member? g.id)
61
+ end
62
+ set.each do |g|
63
+ old_children.delete(g)
64
+ end
65
+
66
+ # add missing and allowed new children
67
+ old_ids = old_children.collect { |g| g.id }
68
+ new_ids.each do |gid|
69
+ old_children << model.get!(gid) if !old_ids.member?(gid) && allowed_ids.member?(gid)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -2,10 +2,14 @@ require 'digest/sha1'
2
2
  require 'base64'
3
3
  require 'ixtlan/modified_by'
4
4
  require 'dm-serializer'
5
+ require 'ixtlan/models/update_children'
5
6
  module Ixtlan
6
7
  module Models
7
8
  class User
8
9
  include DataMapper::Resource
10
+ include UpdateChildren
11
+
12
+ GROUP = Object.full_const_get(Models::GROUP)
9
13
 
10
14
  def self.default_storage_name
11
15
  "User"
@@ -13,15 +17,15 @@ module Ixtlan
13
17
 
14
18
  property :id, Serial, :field => "uidnumber"
15
19
 
16
- property :login, String, :nullable => false , :length => 4..32, :index => :unique_index, :format => /^[a-zA-z0-9]*$/, :writer => :private, :field => "uid"
20
+ property :login, String, :required => true, :field => "uid", :length => 4..32, :unique_index => true, :format => /^[a-zA-Z0-9]*$/, :writer => :private
17
21
 
18
- property :name, String, :nullable => false, :format => /^[^<">]*$/, :length => 2..64, :field => "cn"
22
+ property :name, String, :required => true, :format => /^[^<">]*$/, :length => 2..64, :field => "cn"
19
23
 
20
- property :email, String, :nullable => false, :format => :email_address, :nullable => false, :length => 8..64, :index => :unique_index, :field => "mail"
24
+ property :email, String, :required => true, :format => :email_address, :required => true, :length => 8..64, :unique_index => true, :field => "mail"
21
25
 
22
- property :language, String, :nullable => false, :format => /[a-z][a-z]/, :length => 2, :field => "preferredlanguage"
26
+ property :language, String, :required => false, :format => /[a-z][a-z]/, :length => 2, :field => "preferredlanguage"
23
27
 
24
- property :hashed_password, String, :nullable => true, :length => 128, :accessor => :private, :field => "userpassword"
28
+ property :hashed_password, String, :required => false, :length => 128, :accessor => :private, :field => "userpassword"
25
29
 
26
30
  timestamps :at
27
31
 
@@ -30,15 +34,15 @@ module Ixtlan
30
34
  # Virtual attribute for the plaintext password
31
35
  attr_reader :password
32
36
 
33
- validates_is_unique :login
34
- validates_is_unique :email
37
+ #validates_is_unique :login
38
+ #validates_is_unique :email
35
39
 
36
40
  def reset_password(len = 12)
37
41
  @password = Ixtlan::Passwords.generate(len)
38
42
  attribute_set(:hashed_password, Ixtlan::Digest.ssha(@password, "--#{Time.now}--#{login}--"))
39
43
  @password
40
44
  end
41
-
45
+
42
46
  def digest
43
47
  ::Base64.decode64(@hashed_password[6,200])
44
48
  end
@@ -58,12 +62,20 @@ module Ixtlan
58
62
  end
59
63
  end
60
64
 
65
+ def self.first_or_get!(id_or_login)
66
+ first(:login => id_or_login) || get!(id_or_login)
67
+ end
68
+
69
+ def self.first_or_get(id_or_login)
70
+ first(:login => id_or_login) || get(id_or_login)
71
+ end
72
+
61
73
  def groups
62
74
  if @groups.nil?
63
75
  # TODO spec the empty array to make sure new relations are stored
64
76
  # in the database or the groups collection is empty before filling it
65
- @groups = ::DataMapper::Collection.new(::DataMapper::Query.new(self.repository, Models::Group), [])
66
- GroupUser.all(:memberuid => login).each do |gu|
77
+ @groups = ::DataMapper::Collection.new(::DataMapper::Query.new(self.repository, GROUP), [])
78
+ GroupUser.all(:memberuid => login).each do |gu|
67
79
  @groups << gu.group
68
80
  end
69
81
  def @groups.user=(user)
@@ -72,22 +84,26 @@ module Ixtlan
72
84
  @groups.user = self
73
85
  def @groups.<<(group)
74
86
  group.locales(@user)
87
+ group.domains(@user)
75
88
  unless member? group
76
89
  gu = GroupUser.create(:memberuid => @user.login, :gidnumber => group.id)
77
90
  super
78
91
  end
79
-
92
+
80
93
  self
81
94
  end
82
-
83
- def @groups.delete(group)
95
+
96
+ def @groups.delete(group)
84
97
  gu = GroupUser.first(:memberuid => @user.login, :gidnumber => group.id)
85
98
  if gu
86
99
  gu.destroy
87
100
  end
88
101
  super
89
102
  end
90
- @groups.each {|g| g.locales(self) }
103
+ @groups.each do |g|
104
+ g.locales(self)
105
+ g.domains(self)
106
+ end
91
107
  end
92
108
  @groups
93
109
  end
@@ -97,13 +113,89 @@ module Ixtlan
97
113
  attribute_set(:login, new_login) if login.nil?
98
114
  end
99
115
 
116
+ def root?
117
+ groups.detect { |g| g.root? } || false
118
+ end
119
+
120
+ def locales_admin?
121
+ groups.detect { |g| g.locales_admin? } || false
122
+ end
123
+
124
+ def domains_admin?
125
+ groups.detect { |g| g.domains_admin? } || false
126
+ end
127
+
128
+ def update_all_children(new_groups)
129
+ if current_user.root?
130
+ # root has no restrictions
131
+ update_children(new_groups, :groups)
132
+ update_locales_domains(new_groups)
133
+ else
134
+ update_restricted_children(new_groups, :groups, current_user.groups)
135
+ if current_user.locales_admin? || current_user.domains_admin?
136
+ # locales/domains admin can use all locales/domains
137
+ update_locales_domains(new_groups)
138
+ end
139
+ if !current_user.locales_admin? || !current_user.domains_admin?
140
+ update_restricted_locales_domains(new_groups, current_user.groups)
141
+ end
142
+ end
143
+ end
144
+
145
+ def update_locales_domains(new_groups)
146
+ if(new_groups)
147
+ # make sure we have an array
148
+ new_groups = new_groups[:group]
149
+ new_groups = [new_groups] unless new_groups.is_a? Array
150
+
151
+ # create a map group_id => group
152
+ user_groups_map = {}
153
+ groups.each { |g| user_groups_map[g.id.to_s] = g }
154
+
155
+ # for each new groups update the locales/domains respectively
156
+ new_groups.each do |group|
157
+ if user_groups_map.key?(group[:id])
158
+ user_groups_map[group[:id]].update_children(group[:locales], :locales) if current_user.locales_admin? || current_user.root?
159
+ user_groups_map[group[:id]].update_children(group[:domains], :domains) if current_user.domains_admin? || current_user.root?
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ def update_restricted_locales_domains(new_groups, ref_groups)
166
+ if(new_groups)
167
+ # make sure we have an array
168
+ new_groups = new_groups[:group]
169
+ new_groups = [new_groups] unless new_groups.is_a? Array
170
+
171
+ # create a map group_id => group
172
+ user_groups_map = {}
173
+ groups.each { |g| user_groups_map[g.id.to_s] = g }
174
+ # create a map group_id => group for the reference group
175
+ ref_group_locales = {}
176
+ ref_groups.each { |g| ref_group_locales[g.id.to_s] = g.locales }
177
+ ref_group_domains = {}
178
+ ref_groups.each { |g| ref_group_domains[g.id.to_s] = g.domains }
179
+
180
+ # for each new groups update the locales respectively
181
+ new_groups.each do |group|
182
+ if user_groups_map.key?(group[:id])
183
+ user_groups_map[group[:id]].update_restricted_children(group[:locales], :locales, ref_group_locales[group[:id]] || []) unless current_user.locales_admin?
184
+ user_groups_map[group[:id]].update_restricted_children(group[:domains], :domains, ref_group_domains[group[:id]] || []) unless current_user.domains_admin?
185
+ end
186
+ end
187
+ end
188
+ end
189
+
100
190
  if protected_instance_methods.find {|m| m == 'to_x'}.nil?
101
- alias :to_x :to_xml_document
191
+ alias :to_x :to_xml_document
102
192
 
103
193
  protected
104
194
 
105
195
  def to_xml_document(opts={}, doc = nil)
106
- opts.merge!({:exclude => [:hashed_password], :methods => [:groups]})
196
+ unless(opts[:methods] || opts[:exclude])
197
+ opts.merge!({:exclude => [:hashed_password], :methods => [:groups]})
198
+ end
107
199
  to_x(opts, doc)
108
200
  end
109
201
  end
@@ -1,10 +1,11 @@
1
+ require 'dm-serializer'
1
2
  module Ixtlan
2
3
  module Models
3
4
  class Word < Ixtlan::Models::I18nText
4
5
 
5
6
  alias :to_x :to_xml_document
6
7
  def to_xml_document(opts, doc = nil)
7
- opts.merge!({:element_name => "word", :exclude => [:id, :locale_code, :current, :previous, :updated_at, :approved_at, :updated_by_id, :approved_by_id, :version]})
8
+ opts.merge!({:element_name => "word", :exclude => [:id, :locale_id, :current, :previous, :updated_at, :approved_at, :updated_by_id, :approved_by_id, :version]})
8
9
  to_x(opts, doc)
9
10
  end
10
11
  end
data/lib/ixtlan/models.rb CHANGED
@@ -6,6 +6,7 @@ module Ixtlan
6
6
  ROLE = "::Ixtlan::Models::Role" unless const_defined? "ROLE"
7
7
  PERMISSION = "::Ixtlan::Models::Permission" unless const_defined? "PERMISSION"
8
8
  LOCALE = "::Ixtlan::Models::Locale" unless const_defined? "LOCALE"
9
+ DOMAIN = "::Ixtlan::Models::Domain" unless const_defined? "DOMAIN"
9
10
  CONFIGURATION = "::Ixtlan::Models::Configuration" unless const_defined? "CONFIGURATION"
10
11
  TRANSLATION = "::Ixtlan::Models::Translation" unless const_defined? "TRANSLATION"
11
12
  TEXT = "::Ixtlan::Models::I18nText" unless const_defined? "TEXT"
@@ -1,12 +1,13 @@
1
1
  #require 'dm-core'
2
2
  module Ixtlan
3
3
 
4
- module ModifiedBy
4
+ module ModifiedBy
5
5
  extend ::DataMapper::Chainable
6
6
 
7
7
  MODIFIED_BY_PROPERTIES = {
8
8
  :updated_by => lambda {|r, u| r.updated_by = u},
9
- :created_by => lambda {|r, u| r.created_by = u if r.new? }
9
+ :created_by => lambda {|r, u| r.created_by = u #if r.new?
10
+ }
10
11
  }.freeze
11
12
 
12
13
  def self.included(model)
@@ -22,7 +23,7 @@ module Ixtlan
22
23
 
23
24
  def current_user
24
25
  raise ::DataMapper::MissingCurrentUserError.new("current_user not set. it can be set like any other property") unless @current_user
25
-
26
+
26
27
  @current_user
27
28
  end
28
29
 
@@ -56,14 +57,15 @@ module Ixtlan
56
57
  end
57
58
 
58
59
  module ClassMethods
59
- def modified_by(type, *names)
60
- if(names.empty?)
61
- modified_by(type, :created_by, :updated_by)
60
+ def modified_by(type, names = nil, options = {})
61
+ if(names.nil?)
62
+ modified_by(type, [:created_by, :updated_by])
62
63
  else
64
+ names = [names] unless names.is_a?(Enumerable)
63
65
  names.each do |name|
64
66
  case name
65
67
  when *MODIFIED_BY_PROPERTIES.keys
66
- belongs_to name, :model => type.to_s
68
+ belongs_to name, options.merge!({:model => type.to_s})
67
69
  else
68
70
  raise ::DataMapper::InvalidModifiedByName, "Invalid 'modified by' name '#{name}'"
69
71
  end
@@ -12,8 +12,8 @@ module Extlib
12
12
  module Assertions
13
13
  def assert_kind_of(name, value, *klasses)
14
14
  # be less strict and allow matching class names to OK as well
15
- klasses.each { |k| return if value.kind_of?(k) or value.class.name == k.name }
16
- raise ArgumentError, "+\#{name}+ should be \#{klasses.map { |k| k.name } * ' or '}, but was \#{value.class.name}", caller(2)
15
+ klasses.each { |k| return if value.kind_of?(k) or value.class.name == k.name }
16
+ raise ArgumentError, "+#{name}+ should be #{klasses.map { |k| k.name } * ' or '}, but was #{value.class.name}", caller(2)
17
17
  end
18
18
  end
19
19
  end
@@ -21,15 +21,15 @@ if RUBY_PLATFORM =~ /java/
21
21
  module DataMapper
22
22
  module Validate
23
23
  class NumericValidator
24
-
24
+
25
25
  def validate_with_comparison(value, cmp, expected, error_message_name, errors, negated = false)
26
26
  return if expected.nil?
27
- if cmp == :=~
27
+ if cmp == :=~
28
28
  return value =~ expected
29
29
  end
30
30
  comparison = value.send(cmp, expected)
31
31
  return if negated ? !comparison : comparison
32
-
32
+
33
33
  errors << ValidationErrors.default_error_message(error_message_name, field_name, expected)
34
34
  end
35
35
  end
@@ -6,9 +6,9 @@ module DataMapper
6
6
 
7
7
  end
8
8
 
9
- module Ixtlan
9
+ module Ixtlan
10
10
  module OptimisticPersistence
11
-
11
+
12
12
  def self.included(base)
13
13
  base.send(:include, ::Ixtlan::OptimisticPersistenceModule)
14
14
  base.before :valid? do
@@ -6,10 +6,10 @@ module Ixtlan
6
6
  qu = {}
7
7
  c = model.key_conditions(repository, key)
8
8
  c.each {|p,v| qu[p.name] = v}
9
-
9
+
10
10
  s = self.model.first(qu)
11
- if s.nil?
12
- false
11
+ if s.nil?
12
+ false
13
13
  else
14
14
  # use to_s to get it to work in both MRI and JRuby
15
15
  s.updated_at.to_s != updated_at.to_s
@@ -3,9 +3,9 @@ require 'ixtlan/optimistic_persistence_module'
3
3
  module DataMapper
4
4
 
5
5
  class StaleResource < StandardError; end
6
-
6
+
7
7
  module OptimisticPersistenceValidation
8
-
8
+
9
9
  def self.included(base)
10
10
  base.send(:include, ::Ixtlan::OptimisticPersistenceModule)
11
11
  base.validates_with_block :stale do
@@ -1,19 +1,21 @@
1
1
  module Ixtlan
2
2
  class Passwords
3
3
  def self.generate(length=64)
4
- # A-Z starting with 97 and having 26 characters
5
- # a-z starting with 65 and having 26 characters
6
- # 0-9 starting with 48 and lies inside range starting with 33 and having 26 characters
7
- offset=[97, 65, 33]
8
-
9
- # collect random characters from the either of the above ranges
10
- begin
11
- pwd = (0..(length - 1)).collect do
12
- j = ActiveSupport::SecureRandom.random_number(78)
13
- (offset[j / 26] + (j % 26)).chr
14
- end.join
15
- end while !((pwd =~ /[a-z]/) && (pwd =~ /[A-Z]/) && (pwd =~ /[!-;]/))
16
- pwd
4
+ if length > 0
5
+ # A-Z starting with 97 and having 26 characters
6
+ # a-z starting with 65 and having 26 characters
7
+ # 0-9 starting with 48 and lies inside range starting with 33 and having 26 characters
8
+ offset=[97, 65, 33]
9
+
10
+ # collect random characters from the either of the above ranges
11
+ begin
12
+ pwd = (0..(length - 1)).collect do
13
+ j = ActiveSupport::SecureRandom.random_number(78)
14
+ (offset[j / 26] + (j % 26)).chr
15
+ end.join
16
+ end while !((pwd =~ /[a-z]/) && (pwd =~ /[A-Z]/) && (pwd =~ /[!-;]/))
17
+ pwd
18
+ end
17
19
  end
18
20
  end
19
21
  end