ixtlan-remote 0.1.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/Gemfile +2 -0
- data/README.md +64 -0
- data/agpl-3.0.txt +661 -0
- data/lib/ixtlan-remote.rb +23 -0
- data/lib/ixtlan/passwords.rb +52 -0
- data/lib/ixtlan/passwords.rb~ +47 -0
- data/lib/ixtlan/railtie.rb~ +17 -0
- data/lib/ixtlan/remote.rb +23 -0
- data/lib/ixtlan/remote/access_controller.rb +62 -0
- data/lib/ixtlan/remote/access_controller.rb~ +25 -0
- data/lib/ixtlan/remote/constant_time_compare.rb +39 -0
- data/lib/ixtlan/remote/constant_time_compare.rb~ +19 -0
- data/lib/ixtlan/remote/heartbeat.rb~ +80 -0
- data/lib/ixtlan/remote/model_conversion.rb~ +245 -0
- data/lib/ixtlan/remote/model_helpers.rb +73 -0
- data/lib/ixtlan/remote/model_helpers.rb~ +53 -0
- data/lib/ixtlan/remote/permission.rb +40 -0
- data/lib/ixtlan/remote/permission.rb~ +19 -0
- data/lib/ixtlan/remote/railtie.rb +30 -0
- data/lib/ixtlan/remote/railtie.rb~ +9 -0
- data/lib/ixtlan/remote/remote_access_controller.rb~ +25 -0
- data/lib/ixtlan/remote/remote_permisson.rb~ +9 -0
- data/lib/ixtlan/remote/resource.rb +145 -0
- data/lib/ixtlan/remote/resource.rb-~ +165 -0
- data/lib/ixtlan/remote/resource.rb~ +152 -0
- data/lib/ixtlan/remote/rest.rb +108 -0
- data/lib/ixtlan/remote/rest.rb~ +83 -0
- data/lib/ixtlan/remote/rest_resource.rb~ +140 -0
- data/lib/ixtlan/remote/rest_resource_config.rb~ +63 -0
- data/lib/ixtlan/remote/rest_resource_factory.rb~ +259 -0
- data/lib/ixtlan/remote/rest_resource_old.rb-~ +259 -0
- data/lib/ixtlan/remote/server.rb +119 -0
- data/lib/ixtlan/remote/server.rb~ +82 -0
- data/lib/ixtlan/remote/summary.rb +46 -0
- data/lib/ixtlan/remote/summary.rb~ +23 -0
- data/lib/ixtlan/remote/sync.rb +104 -0
- data/lib/ixtlan/remote/sync.rb~ +78 -0
- data/lib/ixtlan/remote/sync_summary.rb~ +23 -0
- data/lib/ixtlan/remote/tranlation_key.rb~ +7 -0
- data/lib/ixtlan/remote/translation.rake~ +194 -0
- data/lib/ixtlan/remote/translation_models.rb~ +11 -0
- data/lib/ixtlan/remote/updater.rb~ +71 -0
- data/lib/ixtlan/user_management/application_model.rb +30 -0
- data/lib/ixtlan/user_management/application_model.rb~ +21 -0
- data/lib/ixtlan/user_management/application_resource.rb +48 -0
- data/lib/ixtlan/user_management/application_resource.rb~ +21 -0
- data/lib/ixtlan/user_management/authentcator.rb~ +31 -0
- data/lib/ixtlan/user_management/authentication_model.rb +31 -0
- data/lib/ixtlan/user_management/authentication_model.rb~ +21 -0
- data/lib/ixtlan/user_management/authenticator.rb +55 -0
- data/lib/ixtlan/user_management/authenticator.rb~ +20 -0
- data/lib/ixtlan/user_management/domain_resource.rb +48 -0
- data/lib/ixtlan/user_management/domain_resource.rb~ +21 -0
- data/lib/ixtlan/user_management/dummy_authentication.rb +50 -0
- data/lib/ixtlan/user_management/dummy_authentication.rb~ +49 -0
- data/lib/ixtlan/user_management/group.rb~ +39 -0
- data/lib/ixtlan/user_management/group_model.rb +31 -0
- data/lib/ixtlan/user_management/group_model.rb~ +21 -0
- data/lib/ixtlan/user_management/models.rb~ +39 -0
- data/lib/ixtlan/user_management/session-serializer.rb~ +18 -0
- data/lib/ixtlan/user_management/session_cuba.rb +47 -0
- data/lib/ixtlan/user_management/session_cuba.rb~ +44 -0
- data/lib/ixtlan/user_management/session_manager.rb +38 -0
- data/lib/ixtlan/user_management/session_model.rb +36 -0
- data/lib/ixtlan/user_management/session_model.rb~ +10 -0
- data/lib/ixtlan/user_management/session_plugin.rb +32 -0
- data/lib/ixtlan/user_management/session_serializer.rb +21 -0
- data/lib/ixtlan/user_management/session_serializer.rb~ +21 -0
- data/lib/ixtlan/user_management/user.rb~ +16 -0
- data/lib/ixtlan/user_management/user_model.rb +36 -0
- data/lib/ixtlan/user_management/user_model.rb~ +33 -0
- data/lib/ixtlan/user_management/user_resource.rb +55 -0
- data/lib/ixtlan/user_management/user_resource.rb~ +24 -0
- data/lib/ixtlan/user_management/user_serializer.rb +15 -0
- data/lib/ixtlan/user_management/user_serializer.rb~ +23 -0
- data/spec/access_controller_spec.rb +65 -0
- data/spec/access_controller_spec.rb~ +65 -0
- data/spec/model_helpers_spec.rb +40 -0
- data/spec/model_helpers_spec.rb~ +36 -0
- data/spec/remote_access_controller_spec.rb~ +36 -0
- data/spec/resource_spec.rb +181 -0
- data/spec/resource_spec.rb~ +173 -0
- data/spec/rest_resource_spec.rb~ +173 -0
- data/spec/rest_spec.rb +94 -0
- data/spec/rest_spec.rb~ +99 -0
- data/spec/rest_with_attribute_name_like_model_name_spec.rb +82 -0
- data/spec/sync_spec.rb +83 -0
- data/spec/sync_spec.rb~ +81 -0
- metadata +313 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class Ixtlan::Remote::Updater
|
|
2
|
+
|
|
3
|
+
class Summary
|
|
4
|
+
|
|
5
|
+
def initialize(clazz)
|
|
6
|
+
@count = 0
|
|
7
|
+
@failures = 0
|
|
8
|
+
@clazz = clazz
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def inc_count
|
|
12
|
+
@count += 1
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def inc_failures
|
|
16
|
+
@falures += 1
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_log
|
|
20
|
+
"update #{@clazz} - total: #{@count + @failures} success: #{@count} failures: #{@failures}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
namespace :ixtlan do
|
|
2
|
+
|
|
3
|
+
namespace :translation do
|
|
4
|
+
desc 'crawls the local filesystem for _(...) method calls and sends the collected translation keys to the remote service'
|
|
5
|
+
task :update => :environment do
|
|
6
|
+
keys = rest.update({:translation_keys => ['ke', 'a']})
|
|
7
|
+
keys.each do |k|
|
|
8
|
+
if tk = TranslationKey.get(k[:id])
|
|
9
|
+
tk.update(k)
|
|
10
|
+
else
|
|
11
|
+
TranslationKey.create(k)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
task :commit => :environment do
|
|
17
|
+
keys = rest.put('translation_keys/commit')
|
|
18
|
+
keys.each do |k|
|
|
19
|
+
if tk = TranslationKey.get(k[:id])
|
|
20
|
+
if tk.state == :deleted
|
|
21
|
+
tk.destroy!
|
|
22
|
+
else
|
|
23
|
+
tk.update(k)
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
TranslationKey.create(k) unless k[:state].to_sym == :deleted
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
task :rollback => :environment do
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
class RestClient
|
|
38
|
+
|
|
39
|
+
def initialize(url)
|
|
40
|
+
@r = RestClient::Resource.new(url)
|
|
41
|
+
# @root = root.to_s
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def resource_name(obj, name = nil)
|
|
45
|
+
n =
|
|
46
|
+
case obj
|
|
47
|
+
when Hash
|
|
48
|
+
args[0].keys.first
|
|
49
|
+
when Array
|
|
50
|
+
if obj.empty?
|
|
51
|
+
name
|
|
52
|
+
else
|
|
53
|
+
resource_name(obj[0])
|
|
54
|
+
end
|
|
55
|
+
else
|
|
56
|
+
obj.class
|
|
57
|
+
end
|
|
58
|
+
n.to_s.underscore.to_sym
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def resource(obj)
|
|
62
|
+
r = @r[resource_name(obj)]
|
|
63
|
+
if params && params['id']
|
|
64
|
+
r = r[params['id']]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
class RestResource
|
|
70
|
+
|
|
71
|
+
def initialize(resource)
|
|
72
|
+
@resource = resource
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def send(&block)
|
|
76
|
+
raise "no method given - call any CRUD method first" unless @method
|
|
77
|
+
headers = {}
|
|
78
|
+
headers[:params] = @params if @params
|
|
79
|
+
result =
|
|
80
|
+
if @payload
|
|
81
|
+
@resource.send @method, @payload.to_json, headers, &block
|
|
82
|
+
else
|
|
83
|
+
@resource.send @method, headers, &block
|
|
84
|
+
end
|
|
85
|
+
result = JSON.load(result)
|
|
86
|
+
if @model
|
|
87
|
+
if result.is_a? Array
|
|
88
|
+
result.collect do |r|
|
|
89
|
+
@model.new(r)
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
@model.new(result)
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
result
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# retrieve(:locales, {:updated_at => ...}).verb(:last_changes) => GET /locales/last_changes?updated=...
|
|
100
|
+
def verb(v)
|
|
101
|
+
@resource = @resource[v.to_s]
|
|
102
|
+
self
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def as_model(obj)
|
|
106
|
+
obj.respond_to?(:model_name) ? obj.model_name : obj.class
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def path(data)
|
|
110
|
+
@model =
|
|
111
|
+
case data
|
|
112
|
+
when Hash
|
|
113
|
+
data.keys.first
|
|
114
|
+
when Array
|
|
115
|
+
if data.empty?
|
|
116
|
+
#TODO
|
|
117
|
+
else
|
|
118
|
+
as_model(data[0])
|
|
119
|
+
end
|
|
120
|
+
else
|
|
121
|
+
as_model(data)
|
|
122
|
+
end
|
|
123
|
+
@model = key.to_s.underscore
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# retrieve(Locale) => GET /locales
|
|
127
|
+
# retrieve(Locale, 1) => GET /locales/1
|
|
128
|
+
# retrieve(Locale, {:updated_at => ...}) => GET /locales?updated=...
|
|
129
|
+
# retrieve(:locales, {:updated_at => ...}) => GET /locales?updated=...
|
|
130
|
+
# retrieve(:locales, 1) => GET /locales/1
|
|
131
|
+
def retrieve(*args)
|
|
132
|
+
@method = :get
|
|
133
|
+
@payload = nil
|
|
134
|
+
if args.last.is_a? Hash
|
|
135
|
+
@params = args.delete_at(args.size - 1)
|
|
136
|
+
else
|
|
137
|
+
@params = nil
|
|
138
|
+
end
|
|
139
|
+
@resource = @base[path(args[0]) + args[1..-1].join('/')]
|
|
140
|
+
self
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# create(locale) => POST /locales
|
|
144
|
+
# create(:locale => {:code => 'en'}) => POST /locales
|
|
145
|
+
def create(obj_or_hash)
|
|
146
|
+
@method = :post
|
|
147
|
+
@payload = obj_or_hash
|
|
148
|
+
@params = nil
|
|
149
|
+
@resource = @base[path(obj_or_hash)]
|
|
150
|
+
self
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def update(obj_or_hash)
|
|
154
|
+
@method = :put
|
|
155
|
+
@payload = obj_or_hash
|
|
156
|
+
@params = nil
|
|
157
|
+
@resource = @base[path(obj_or_hash)]
|
|
158
|
+
self
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def delete(obj_or_hash)
|
|
162
|
+
@method = :delete
|
|
163
|
+
@payload = obj_or_hash
|
|
164
|
+
@params = nil
|
|
165
|
+
@resource = @base[path(obj_or_hash)]
|
|
166
|
+
self
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
class ResourceFactory
|
|
172
|
+
|
|
173
|
+
def resource(key)
|
|
174
|
+
k = key.to_s.underscore.to_sym
|
|
175
|
+
RestClient::Resource.new("http://localhost:#{port}/#{key}")
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def method_missing(method, *args)
|
|
179
|
+
case args[0]
|
|
180
|
+
when Hash
|
|
181
|
+
r = resource(args[0].keys.first)
|
|
182
|
+
when Array
|
|
183
|
+
if args[0].empty?
|
|
184
|
+
r = resource(args[1])
|
|
185
|
+
else
|
|
186
|
+
r = resource(args[0][0].class)
|
|
187
|
+
end
|
|
188
|
+
else
|
|
189
|
+
r = resource(args[0].class)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'ixtlan/remote/summary'
|
|
2
|
+
|
|
3
|
+
class Ixtlan::Remote::Updater
|
|
4
|
+
|
|
5
|
+
def initialize(restserver)
|
|
6
|
+
@restserver = restserver
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def clazzes
|
|
10
|
+
@clazzes ||= {}
|
|
11
|
+
end
|
|
12
|
+
private :clazzes
|
|
13
|
+
|
|
14
|
+
def register(clazz, &block)
|
|
15
|
+
c = clazz.to_s.pluralize.underscore
|
|
16
|
+
clazzes[c] = block unless clazzes.key?(c)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# max method ORM dependent
|
|
20
|
+
if defined? ActiveRecord
|
|
21
|
+
def max(clazz)
|
|
22
|
+
@restserver.to_class(clazz).maximum(:updated_at)
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
def max(clazz)
|
|
26
|
+
@restserver.to_class(clazz).max(:updated_at)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
private :max
|
|
30
|
+
|
|
31
|
+
# UTC timestamp of last updated record
|
|
32
|
+
def last_update(clazz)
|
|
33
|
+
@last_update ||=
|
|
34
|
+
begin
|
|
35
|
+
last_date = (max(clazz) || 2000.years.ago) + Date::SECONDS_IN_DAY
|
|
36
|
+
last_date.strftime('%Y-%m-%d %H:%M:%S.') + ("%06d" % (last_date.sec_fraction / Date::NANOSECONDS_IN_DAY / 1000)) + "+0:00"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
private :last_update
|
|
40
|
+
|
|
41
|
+
# load the last changed records
|
|
42
|
+
def do_it(set = clazzes.keys)
|
|
43
|
+
@last_result = []
|
|
44
|
+
set = [set.to_s.pluralize] unless set.is_a? Array
|
|
45
|
+
set.to_a.each do |clazz|
|
|
46
|
+
summary = Summary.new(clazz)
|
|
47
|
+
@last_result << summary
|
|
48
|
+
@restserver.retrieve(clazz,
|
|
49
|
+
:last_changes,
|
|
50
|
+
:updated_at => last_update(clazz)).each do |item|
|
|
51
|
+
if item.save
|
|
52
|
+
summary.inc_count
|
|
53
|
+
else
|
|
54
|
+
summary.inc_failures
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
b = clazzes[clazz]
|
|
58
|
+
b.call summary if b
|
|
59
|
+
end
|
|
60
|
+
to_log
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_log
|
|
64
|
+
if @last_result
|
|
65
|
+
@last_result.collect { |r| r.to_log }.join("\n\t")
|
|
66
|
+
else
|
|
67
|
+
"no results yet"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
alias :to_s :to_log
|
|
71
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#
|
|
2
|
+
# ixtlan-remote - helper sync data between miniapps or communicate wth realtime
|
|
3
|
+
# rest-services
|
|
4
|
+
# Copyright (C) 2012 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# This file is part of ixtlan-remote.
|
|
7
|
+
#
|
|
8
|
+
# ixtlan-remote is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Affero General Public License as
|
|
10
|
+
# published by the Free Software Foundation, either version 3 of the
|
|
11
|
+
# License, or (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# ixtlan-remote is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU Affero General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
# along with ixtlan-remote. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
module Ixtlan
|
|
22
|
+
module UserManagement
|
|
23
|
+
class Application
|
|
24
|
+
include Virtus
|
|
25
|
+
|
|
26
|
+
attribute :name, String
|
|
27
|
+
attribute :url, String
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Ixtlan
|
|
2
|
+
module UserManagement
|
|
3
|
+
class Application
|
|
4
|
+
include Virtus
|
|
5
|
+
|
|
6
|
+
attribute :name, String
|
|
7
|
+
attribute :url, String
|
|
8
|
+
end
|
|
9
|
+
class Group
|
|
10
|
+
include Virtus
|
|
11
|
+
|
|
12
|
+
attribute :name, String
|
|
13
|
+
end
|
|
14
|
+
class Authentication
|
|
15
|
+
include Virtus
|
|
16
|
+
|
|
17
|
+
attribute :login, String
|
|
18
|
+
attribute :password, String
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#
|
|
2
|
+
# ixtlan-remote - helper sync data between miniapps or communicate wth realtime
|
|
3
|
+
# rest-services
|
|
4
|
+
# Copyright (C) 2012 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# This file is part of ixtlan-remote.
|
|
7
|
+
#
|
|
8
|
+
# ixtlan-remote is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU Affero General Public License as
|
|
10
|
+
# published by the Free Software Foundation, either version 3 of the
|
|
11
|
+
# License, or (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# ixtlan-remote is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU Affero General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
# along with ixtlan-remote. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
module Ixtlan
|
|
22
|
+
module UserManagement
|
|
23
|
+
class Application
|
|
24
|
+
include DataMapper::Resource
|
|
25
|
+
|
|
26
|
+
def self.storage_name(arg)
|
|
27
|
+
'ixtlan_applications'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# key for selectng the IdentityMap should remain this class if
|
|
31
|
+
# there is no single table inheritance with Discriminator in place
|
|
32
|
+
# i.e. the subclass used as key for the IdentityMap
|
|
33
|
+
def self.base_model
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
property :id, Serial, :auto_validation => false
|
|
38
|
+
|
|
39
|
+
property :name, String, :required => true, :unique => true, :length => 32
|
|
40
|
+
property :url, String, :required => true, :format => /^https?\:\/\/[a-z0-9\-\.]+(\.[a-z0-9]+)*(\:[0-9]+)?(\/\S*)?$/, :length => 64, :lazy => true
|
|
41
|
+
property :updated_at, DateTime, :required => true, :lazy => true
|
|
42
|
+
|
|
43
|
+
# do not record timestamps since they are set from outside
|
|
44
|
+
def set_timestamps_on_save
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Ixtlan
|
|
2
|
+
module UserManagement
|
|
3
|
+
class Application
|
|
4
|
+
include DataMapper::Resource
|
|
5
|
+
|
|
6
|
+
def self.storage_name(arg)
|
|
7
|
+
'ixtlan_applications'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
property :id, Serial, :auto_validation => false
|
|
11
|
+
|
|
12
|
+
property :name, String, :required => true, :unique => true, :length => 32
|
|
13
|
+
property :url, String, :required => true, :format => /^https?\:\/\/[a-z0-9\-\.]+(\.[a-z0-9]+)*(\:[0-9]+)?(\/\S*)?$/, :length => 64, :lazy => true
|
|
14
|
+
property :updated_at, DateTime, :required => true, :lazy => true
|
|
15
|
+
|
|
16
|
+
# do not record timestamps since they are set from outside
|
|
17
|
+
def set_timestamps_on_save
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Ixtlan
|
|
2
|
+
module UserManagement
|
|
3
|
+
class User
|
|
4
|
+
|
|
5
|
+
include DataMapper::Resource
|
|
6
|
+
|
|
7
|
+
def self.storage_name(arg)
|
|
8
|
+
'ixtlan_users'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# key for selectng the IdentityMap should remain this class if
|
|
12
|
+
# there is no single table inheritance with Discriminator in place
|
|
13
|
+
# i.e. the subclass used as key for the IdentityMap
|
|
14
|
+
def self.base_model
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
property :id, Serial, :auto_validation => false
|
|
19
|
+
|
|
20
|
+
property :login, String, :required => true, :unique => true, :length => 32
|
|
21
|
+
property :name, String, :required => true, :length => 128
|
|
22
|
+
property :updated_at, DateTime, :required => true
|
|
23
|
+
|
|
24
|
+
attr_accessor :groups, :applications
|
|
25
|
+
|
|
26
|
+
# do not record timestamps since they are set from outside
|
|
27
|
+
def set_timestamps_on_save
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|