zimbra-soap-api 0.0.7.9
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.irbrc +6 -0
- data/Gemfile +6 -0
- data/README +21 -0
- data/Rakefile +1 -0
- data/lib/zimbra.rb +94 -0
- data/lib/zimbra/account.rb +94 -0
- data/lib/zimbra/acl.rb +63 -0
- data/lib/zimbra/alias.rb +4 -0
- data/lib/zimbra/appointment.rb +274 -0
- data/lib/zimbra/appointment/alarm.rb +101 -0
- data/lib/zimbra/appointment/attendee.rb +97 -0
- data/lib/zimbra/appointment/invite.rb +360 -0
- data/lib/zimbra/appointment/recur_exception.rb +83 -0
- data/lib/zimbra/appointment/recur_rule.rb +184 -0
- data/lib/zimbra/appointment/reply.rb +91 -0
- data/lib/zimbra/auth.rb +46 -0
- data/lib/zimbra/base.rb +217 -0
- data/lib/zimbra/calendar.rb +27 -0
- data/lib/zimbra/common_elements.rb +51 -0
- data/lib/zimbra/cos.rb +124 -0
- data/lib/zimbra/delegate_auth_token.rb +49 -0
- data/lib/zimbra/directory.rb +175 -0
- data/lib/zimbra/distribution_list.rb +147 -0
- data/lib/zimbra/domain.rb +63 -0
- data/lib/zimbra/ext/handsoap_curb_driver.rb +21 -0
- data/lib/zimbra/ext/hash.rb +72 -0
- data/lib/zimbra/ext/string.rb +10 -0
- data/lib/zimbra/extra/date_helpers.rb +111 -0
- data/lib/zimbra/folder.rb +100 -0
- data/lib/zimbra/handsoap_account_service.rb +44 -0
- data/lib/zimbra/handsoap_service.rb +75 -0
- data/lib/zimbra/version.rb +3 -0
- data/spec/fixtures/xml_api_requests/appointments/create.xml +84 -0
- data/spec/fixtures/xml_api_responses/alarms/15_minutes_before.xml +26 -0
- data/spec/fixtures/xml_api_responses/alarms/using_all_intervals.xml +26 -0
- data/spec/fixtures/xml_api_responses/appointments/appointment_response_1.xml +40 -0
- data/spec/fixtures/xml_api_responses/attendees/one_attendee_and_one_reply.xml +27 -0
- data/spec/fixtures/xml_api_responses/attendees/three_attendees_response_1.xml +30 -0
- data/spec/fixtures/xml_api_responses/multiple_invites/recurring_with_exceptions.xml +109 -0
- data/spec/fixtures/xml_api_responses/recur_rules/day_27_of_every_2_months.xml +27 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_2_days.xml +26 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_3_weeks_on_tuesday_and_friday.xml +30 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_day_50_instances.xml +27 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_monday_wednesday_friday.xml +31 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_tuesday.xml +29 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_weekday_with_end_date.xml +34 -0
- data/spec/fixtures/xml_api_responses/recur_rules/every_year_on_february_2.xml +28 -0
- data/spec/fixtures/xml_api_responses/recur_rules/first_day_of_every_month.xml +36 -0
- data/spec/fixtures/xml_api_responses/recur_rules/first_monday_of_every_february.xml +31 -0
- data/spec/fixtures/xml_api_responses/recur_rules/first_weekend_day_of_every_month.xml +31 -0
- data/spec/fixtures/xml_api_responses/recur_rules/last_day_of_every_month.xml +36 -0
- data/spec/fixtures/xml_api_responses/recur_rules/second_day_of_every_2_months.xml +36 -0
- data/spec/fixtures/xml_api_responses/recur_rules/second_wednesday_of_every_month.xml +29 -0
- data/spec/fixtures/xml_api_responses/recur_rules/weekly_with_an_exception.xml +44 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/zimbra/acl_spec.rb +11 -0
- data/spec/zimbra/appointment/alarm_spec.rb +33 -0
- data/spec/zimbra/appointment/invite_spec.rb +62 -0
- data/spec/zimbra/appointment/recur_rule_spec.rb +307 -0
- data/spec/zimbra/appointment_spec.rb +175 -0
- data/spec/zimbra/common_elements_spec.rb +33 -0
- data/spec/zimbra/distribution_list_spec.rb +54 -0
- data/zimbra.gemspec +28 -0
- metadata +197 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
module Zimbra
|
2
|
+
class Appointment
|
3
|
+
class RecurException
|
4
|
+
class << self
|
5
|
+
def new_from_zimbra_attributes(zimbra_attributes)
|
6
|
+
return nil unless zimbra_attributes
|
7
|
+
new(parse_zimbra_attributes(zimbra_attributes))
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse_zimbra_attributes(zimbra_attributes)
|
11
|
+
zimbra_attributes = Zimbra::Hash.symbolize_keys(zimbra_attributes.dup, true)
|
12
|
+
|
13
|
+
{
|
14
|
+
:recurrence_id => zimbra_attributes[:d],
|
15
|
+
:timezone => zimbra_attributes[:tz],
|
16
|
+
:range_type => zimbra_attributes[:rangeType]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
ATTRS = [
|
22
|
+
:recurrence_id,
|
23
|
+
:timezone,
|
24
|
+
:range_type
|
25
|
+
] unless const_defined?(:ATTRS)
|
26
|
+
|
27
|
+
attr_accessor *ATTRS
|
28
|
+
|
29
|
+
def range_type=(val)
|
30
|
+
@range_type = parse_range_type(val)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(args = {})
|
34
|
+
self.attributes = args
|
35
|
+
end
|
36
|
+
|
37
|
+
# take attributes by the xml name or our more descriptive name
|
38
|
+
def attributes=(args = {})
|
39
|
+
ATTRS.each do |attr_name|
|
40
|
+
self.send(:"#{attr_name}=", (args[attr_name] || args[attr_name.to_s]))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_hash(options = {})
|
45
|
+
hash = ATTRS.inject({}) do |attr_hash, attr_name|
|
46
|
+
attr_hash[attr_name] = self.send(:"#{attr_name}")
|
47
|
+
attr_hash
|
48
|
+
end
|
49
|
+
hash.reject! { |key, value| options[:except].include?(key.to_sym) || options[:except].include?(key.to_s) } if options[:except]
|
50
|
+
hash.reject! { |key, value| !options[:only].include?(key.to_sym) && !options[:only].include?(key.to_s) } if options[:only]
|
51
|
+
hash
|
52
|
+
end
|
53
|
+
|
54
|
+
def range_type_to_zimbra
|
55
|
+
possible_range_type_values.find { |k, v| v == range_type }.first rescue range_type
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_xml(document)
|
59
|
+
document.add "exceptId" do |except_element|
|
60
|
+
except_element.set_attr "d", recurrence_id
|
61
|
+
except_element.set_attr "tz", timezone
|
62
|
+
except_element.set_attr "rangeType", range_type_to_zimbra if range_type
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def possible_range_type_values
|
69
|
+
@possible_range_type_values ||= {
|
70
|
+
1 => :none,
|
71
|
+
2 => :this_and_future,
|
72
|
+
3 => :this_and_prior
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_range_type(val)
|
77
|
+
int_val = val.to_int rescue nil
|
78
|
+
|
79
|
+
possible_range_type_values[int_val] || val
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
module Zimbra
|
2
|
+
class Appointment
|
3
|
+
class RecurRule
|
4
|
+
class << self
|
5
|
+
def new_from_zimbra_attributes(zimbra_attributes)
|
6
|
+
return nil unless zimbra_attributes
|
7
|
+
new(parse_zimbra_attributes(zimbra_attributes))
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse_zimbra_attributes(zimbra_attributes)
|
11
|
+
attrs = {}
|
12
|
+
|
13
|
+
zimbra_attributes = Zimbra::Hash.symbolize_keys(zimbra_attributes.dup, true)
|
14
|
+
zimbra_attributes = zimbra_attributes[:add][:rule]
|
15
|
+
|
16
|
+
attrs[:frequency] = zimbra_attributes[:attributes][:freq] if zimbra_attributes[:attributes]
|
17
|
+
attrs[:until_date] = zimbra_attributes[:until][:attributes][:d] if zimbra_attributes[:until]
|
18
|
+
attrs[:interval] = zimbra_attributes[:interval][:attributes][:ival] if zimbra_attributes[:interval]
|
19
|
+
attrs[:count] = zimbra_attributes[:count][:attributes][:num] if zimbra_attributes[:count]
|
20
|
+
|
21
|
+
if zimbra_attributes[:bysetpos]
|
22
|
+
attrs[:by_set_position] = zimbra_attributes[:bysetpos][:attributes][:poslist]
|
23
|
+
attrs[:by_set_position] = [attrs[:by_set_position]] unless attrs[:by_set_position].is_a?(Array)
|
24
|
+
end
|
25
|
+
|
26
|
+
if zimbra_attributes[:byday] && zimbra_attributes[:byday][:wkday] && zimbra_attributes[:byday][:wkday].is_a?(Array)
|
27
|
+
attrs[:by_day] = zimbra_attributes[:byday][:wkday].collect do |wkday|
|
28
|
+
wkday = Zimbra::Hash.symbolize_keys(wkday, true)
|
29
|
+
wkday_hash = { day: wkday[:attributes][:day] }
|
30
|
+
wkday_hash[:week_number] = wkday[:attributes][:ordwk] if wkday[:attributes][:ordwk]
|
31
|
+
wkday_hash
|
32
|
+
end
|
33
|
+
elsif zimbra_attributes[:byday] && zimbra_attributes[:byday][:wkday]
|
34
|
+
day_hash = { day: zimbra_attributes[:byday][:wkday][:attributes][:day] }
|
35
|
+
day_hash[:week_number] = zimbra_attributes[:byday][:wkday][:attributes][:ordwk] if zimbra_attributes[:byday][:wkday][:attributes][:ordwk]
|
36
|
+
attrs[:by_day] = [day_hash]
|
37
|
+
end
|
38
|
+
|
39
|
+
if zimbra_attributes[:bymonth]
|
40
|
+
attrs[:by_month] = zimbra_attributes[:bymonth][:attributes][:molist]
|
41
|
+
attrs[:by_month] = [attrs[:by_month]] unless attrs[:by_month].is_a?(Array)
|
42
|
+
end
|
43
|
+
|
44
|
+
if zimbra_attributes[:bymonthday]
|
45
|
+
attrs[:by_month_day] = zimbra_attributes[:bymonthday][:attributes][:modaylist]
|
46
|
+
attrs[:by_month_day] = [attrs[:by_month_day]] unless attrs[:by_month_day].is_a?(Array)
|
47
|
+
end
|
48
|
+
|
49
|
+
attrs
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
ATTRS = [
|
54
|
+
:frequency,
|
55
|
+
:interval,
|
56
|
+
:by_day,
|
57
|
+
:by_month,
|
58
|
+
:by_month_day,
|
59
|
+
:count,
|
60
|
+
:until_date,
|
61
|
+
:by_set_position
|
62
|
+
] unless const_defined?(:ATTRS)
|
63
|
+
|
64
|
+
attr_accessor *ATTRS
|
65
|
+
|
66
|
+
def initialize(args = {})
|
67
|
+
self.attributes = args
|
68
|
+
end
|
69
|
+
|
70
|
+
# take attributes by the xml name or our more descriptive name
|
71
|
+
def attributes=(args = {})
|
72
|
+
ATTRS.each do |attr_name|
|
73
|
+
if args.has_key?(attr_name)
|
74
|
+
self.send(:"#{attr_name}=", args[attr_name])
|
75
|
+
elsif args.has_key?(attr_name.to_s)
|
76
|
+
self.send(:"#{attr_name}=", args[attr_name.to_s])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def frequency=(val)
|
82
|
+
frequency = Zimbra::DateHelpers::Frequency.find(val).name
|
83
|
+
@frequency = frequency || val
|
84
|
+
end
|
85
|
+
|
86
|
+
def frequency_to_zimbra
|
87
|
+
Zimbra::DateHelpers::Frequency.find(frequency).zimbra_name rescue frequency
|
88
|
+
end
|
89
|
+
|
90
|
+
def until_date=(val)
|
91
|
+
@until_date = Time.parse(val) rescue val
|
92
|
+
end
|
93
|
+
|
94
|
+
def by_set_position=(val)
|
95
|
+
if val == [0]
|
96
|
+
@by_set_position = nil
|
97
|
+
else
|
98
|
+
@by_set_position = val
|
99
|
+
end
|
100
|
+
end
|
101
|
+
def by_day=(val)
|
102
|
+
@by_day = if val.is_a?(Array)
|
103
|
+
val.collect do |day_specification|
|
104
|
+
day_specification[:day] = Zimbra::DateHelpers::WeekDay.find(day_specification[:day]) rescue day_specification[:day]
|
105
|
+
day_specification
|
106
|
+
end
|
107
|
+
else
|
108
|
+
val
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_hash(options = {})
|
113
|
+
hash = {
|
114
|
+
:frequency => frequency ? frequency.to_sym : nil,
|
115
|
+
:interval => interval,
|
116
|
+
:by_month => by_month,
|
117
|
+
:by_month_day => by_month_day,
|
118
|
+
:count => count,
|
119
|
+
:until_date => until_date,
|
120
|
+
:by_set_position => by_set_position
|
121
|
+
}
|
122
|
+
hash[:by_day] = by_day.collect do |day_specification|
|
123
|
+
day_specification[:day] = day_specification[:day].to_sym if day_specification[:day]
|
124
|
+
day_specification
|
125
|
+
end if by_day
|
126
|
+
hash.reject! { |key, value| value.nil? }
|
127
|
+
hash.reject! { |key, value| options[:except].include?(key.to_sym) || options[:except].include?(key.to_s) } if options[:except]
|
128
|
+
hash.reject! { |key, value| !options[:only].include?(key.to_sym) && !options[:only].include?(key.to_s) } if options[:only]
|
129
|
+
hash
|
130
|
+
end
|
131
|
+
|
132
|
+
def create_xml(document)
|
133
|
+
document.add "rule" do |rule_element|
|
134
|
+
rule_element.set_attr "freq", frequency_to_zimbra
|
135
|
+
|
136
|
+
if until_date
|
137
|
+
rule_element.add "until" do |until_element|
|
138
|
+
until_element.set_attr "d", until_date.utc.strftime("%Y%m%dT%H%M%SZ")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
rule_element.add "interval" do |interval_element|
|
143
|
+
interval_element.set_attr "ival", interval
|
144
|
+
end
|
145
|
+
|
146
|
+
if count && count > 0
|
147
|
+
rule_element.add "count" do |count_element|
|
148
|
+
count_element.set_attr "num", count
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
if by_day && by_day.count > 0
|
153
|
+
rule_element.add "byday" do |by_day_element|
|
154
|
+
by_day.each do |day_spec|
|
155
|
+
by_day_element.add "wkday" do |wkday_element|
|
156
|
+
wkday_element.set_attr "day", day_spec[:day].zimbra_name
|
157
|
+
wkday_element.set_attr "ordwk", day_spec[:week_number] if day_spec.has_key?(:week_number)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
if by_month && by_month.count > 0
|
164
|
+
rule_element.add "bymonth" do |by_month_element|
|
165
|
+
by_month_element.set_attr "molist", by_month.join(',')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
if by_month_day && by_month_day.count > 0
|
170
|
+
rule_element.add "bymonthday" do |by_month_day_element|
|
171
|
+
by_month_day_element.set_attr "modaylist", by_month_day.join(',')
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
if by_set_position
|
176
|
+
rule_element.add "bysetpos" do |bysetpos_element|
|
177
|
+
bysetpos_element.set_attr "poslist", by_set_position.join(',')
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Zimbra
|
2
|
+
class Appointment
|
3
|
+
class Reply
|
4
|
+
ATTRS = [
|
5
|
+
:sequence_number, :date, :email_address, :participation_status, :sent_by, :recurrence_range_type, :recurrence_id, :timezone, :recurrence_id_utc
|
6
|
+
] unless const_defined?(:ATTRS)
|
7
|
+
|
8
|
+
attr_accessor *ATTRS
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def new_from_zimbra_attributes(zimbra_attributes)
|
12
|
+
new(parse_zimbra_attributes(zimbra_attributes))
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_zimbra_attributes(zimbra_attributes)
|
16
|
+
zimbra_attributes = Zimbra::Hash.symbolize_keys(zimbra_attributes.dup, true)
|
17
|
+
|
18
|
+
{
|
19
|
+
:sequence_number => zimbra_attributes[:seq],
|
20
|
+
:date => zimbra_attributes[:d],
|
21
|
+
:email_address => zimbra_attributes[:at],
|
22
|
+
:participation_status => zimbra_attributes[:ptst],
|
23
|
+
:sent_by => zimbra_attributes[:sentBy],
|
24
|
+
:recurrence_range_type => zimbra_attributes[:rangeType],
|
25
|
+
:recurrence_id => zimbra_attributes[:recurId],
|
26
|
+
:timezone => zimbra_attributes[:tz],
|
27
|
+
:recurrence_id_utc => zimbra_attributes[:ridZ]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(args = {})
|
33
|
+
self.attributes = args
|
34
|
+
end
|
35
|
+
|
36
|
+
# take attributes by the xml name or our more descriptive name
|
37
|
+
def attributes=(args = {})
|
38
|
+
ATTRS.each do |attr_name|
|
39
|
+
if args.has_key?(attr_name)
|
40
|
+
self.send(:"#{attr_name}=", args[attr_name])
|
41
|
+
elsif args.has_key?(attr_name.to_s)
|
42
|
+
self.send(:"#{attr_name}=", args[attr_name.to_s])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def participation_status=(val)
|
48
|
+
@participation_status = parse_participation_status(val)
|
49
|
+
end
|
50
|
+
|
51
|
+
def date=(val)
|
52
|
+
if val.is_a?(Integer)
|
53
|
+
@date = parse_date_in_seconds(val)
|
54
|
+
else
|
55
|
+
@date = val
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_hash(options = {})
|
60
|
+
hash = ATTRS.inject({}) do |hash, attr_name|
|
61
|
+
hash[attr_name] = self.send(attr_name)
|
62
|
+
hash
|
63
|
+
end
|
64
|
+
hash.reject! { |key, value| options[:except].include?(key.to_sym) || options[:except].include?(key.to_s) } if options[:except]
|
65
|
+
hash.reject! { |key, value| !options[:only].include?(key.to_sym) && !options[:only].include?(key.to_s) } if options[:only]
|
66
|
+
hash
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def parse_participation_status(status)
|
72
|
+
possible_values = {
|
73
|
+
'NE' => :needs_action,
|
74
|
+
'AC' => :accept,
|
75
|
+
'TE' => :tentative,
|
76
|
+
'DE' => :declined,
|
77
|
+
'DG' => :delegated,
|
78
|
+
'CO' => :completed,
|
79
|
+
'IN' => :in_process,
|
80
|
+
'WE' => :waiting,
|
81
|
+
'DF' => :deferred
|
82
|
+
}
|
83
|
+
possible_values[status] || status
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_date_in_seconds(seconds)
|
87
|
+
Time.at(seconds / 1000)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/zimbra/auth.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Zimbra
|
2
|
+
class Auth
|
3
|
+
def self.login(username, password)
|
4
|
+
AuthService.login(username, password)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class AuthService < Handsoap::Service
|
9
|
+
include HandsoapErrors
|
10
|
+
include Zimbra::HandsoapNamespaces
|
11
|
+
extend HandsoapUriOverrides
|
12
|
+
|
13
|
+
def on_create_document(doc)
|
14
|
+
request_namespaces(doc)
|
15
|
+
end
|
16
|
+
def on_response_document(doc)
|
17
|
+
response_namespaces(doc)
|
18
|
+
end
|
19
|
+
|
20
|
+
def login(username, password)
|
21
|
+
xml = invoke('n2:AuthRequest') do |message|
|
22
|
+
Builder.auth(message, username, password)
|
23
|
+
end
|
24
|
+
[Parser.auth_token(xml), Parser.session_lifetime(xml)]
|
25
|
+
end
|
26
|
+
|
27
|
+
class Builder
|
28
|
+
class << self
|
29
|
+
def auth(message, username, password)
|
30
|
+
message.add 'name', username
|
31
|
+
message.add 'password', password
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
class Parser
|
36
|
+
class << self
|
37
|
+
def auth_token(response)
|
38
|
+
(response/'//n2:authToken').to_s
|
39
|
+
end
|
40
|
+
def session_lifetime(response)
|
41
|
+
(response/'//n2:lifetime').to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/zimbra/base.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
module Zimbra
|
2
|
+
|
3
|
+
# Doc Placeholder
|
4
|
+
class Base
|
5
|
+
NAMESPACES = {
|
6
|
+
'Domain' => 'domain',
|
7
|
+
'Account' => 'account',
|
8
|
+
'DistributionList' => 'dl'
|
9
|
+
}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def class_name
|
13
|
+
name.gsub(/Zimbra::/, '')
|
14
|
+
end
|
15
|
+
|
16
|
+
def all
|
17
|
+
BaseService.all(class_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_by_id(id)
|
21
|
+
BaseService.get_by_id(id, class_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_by_name(name)
|
25
|
+
BaseService.get_by_name(name, class_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create(name, attrs = {})
|
29
|
+
BaseService.create(name, attrs, class_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_accessor :id, :name, :zimbra_attrs
|
35
|
+
|
36
|
+
def initialize(id, name, zimbra_attrs = {}, node = nil)
|
37
|
+
self.id = id
|
38
|
+
self.name = name
|
39
|
+
self.zimbra_attrs = zimbra_attrs
|
40
|
+
end
|
41
|
+
|
42
|
+
def acls
|
43
|
+
@acls ||= Zimbra::Directory.get_grants(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete
|
47
|
+
BaseService.delete(id, self.class.class_name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def modify(attrs = {})
|
51
|
+
rename(attrs.delete('name')) if attrs['name']
|
52
|
+
BaseService.modify(id, attrs, self.class.class_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Zimbra only allows renaming domains directly through LDAP
|
56
|
+
def rename(newname)
|
57
|
+
fail Zimbra::HandsoapErrors::NotImplemented.new('Rename domain only via LDAP') if self.is_a?(Zimbra::Domain)
|
58
|
+
BaseService.rename(id, newname, self.class.class_name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def zimbra_type
|
62
|
+
Zimbra::Directory::TARGET_TYPES_MAPPING[self.class]
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
# Doc Placeholder
|
68
|
+
class BaseService < HandsoapService
|
69
|
+
def all(class_name)
|
70
|
+
request_name = "n2:GetAll#{class_name}sRequest"
|
71
|
+
xml = invoke(request_name)
|
72
|
+
Parser.get_all_response(class_name, xml)
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete(id, class_name)
|
76
|
+
request_name = "n2:Delete#{class_name}Request"
|
77
|
+
xml = invoke(request_name) do |message|
|
78
|
+
Builder.delete(message, id)
|
79
|
+
end
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
83
|
+
def create(name, attributes = {}, class_name)
|
84
|
+
request_name = "n2:Create#{class_name}Request"
|
85
|
+
xml = invoke(request_name) do |message|
|
86
|
+
Builder.create(message, name, attributes)
|
87
|
+
end
|
88
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
89
|
+
Parser.response(class_name, xml/"//n2:#{namespace}")
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_by_id(id, class_name)
|
93
|
+
request_name = "n2:Get#{class_name}Request"
|
94
|
+
xml = invoke(request_name) do |message|
|
95
|
+
Builder.get_by_id(message, id, class_name)
|
96
|
+
end
|
97
|
+
return nil if soap_fault_not_found?
|
98
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
99
|
+
Parser.response(class_name, xml/"//n2:#{namespace}")
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_by_name(name, class_name)
|
103
|
+
request_name = "n2:Get#{class_name}Request"
|
104
|
+
xml = invoke(request_name) do |message|
|
105
|
+
Builder.get_by_name(message, name, class_name)
|
106
|
+
end
|
107
|
+
return nil if soap_fault_not_found?
|
108
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
109
|
+
Parser.response(class_name, xml/"//n2:#{namespace}")
|
110
|
+
end
|
111
|
+
|
112
|
+
def modify(id, attributes = {}, class_name)
|
113
|
+
request_name = "n2:Modify#{class_name}Request"
|
114
|
+
xml = invoke(request_name) do |message|
|
115
|
+
Builder.modify(message, id, attributes)
|
116
|
+
end
|
117
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
118
|
+
Parser.response(class_name, xml/"//n2:#{namespace}")
|
119
|
+
end
|
120
|
+
|
121
|
+
def rename(id, newname, class_name)
|
122
|
+
request_name = "n2:Rename#{class_name}Request"
|
123
|
+
xml = invoke(request_name) do |message|
|
124
|
+
Builder.rename(message, id, newname)
|
125
|
+
end
|
126
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
127
|
+
Parser.response(class_name, xml/"//n2:#{namespace}")
|
128
|
+
end
|
129
|
+
|
130
|
+
# Doc Placeholder
|
131
|
+
class Builder
|
132
|
+
class << self
|
133
|
+
|
134
|
+
def create(message, name, attributes = {})
|
135
|
+
message.add 'name', name
|
136
|
+
attributes.each do |k,v|
|
137
|
+
A.inject(message, k, v)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def delete(message, id)
|
142
|
+
message.set_attr 'id', id
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_by_id(message, id, class_name)
|
146
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
147
|
+
message.add namespace, id do |c|
|
148
|
+
c.set_attr 'by', 'id'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_by_name(message, name, class_name)
|
153
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
154
|
+
message.add namespace, name do |c|
|
155
|
+
c.set_attr 'by', 'name'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def modify(message, id, attributes)
|
160
|
+
message.add 'id', id
|
161
|
+
modify_attributes(message, attributes)
|
162
|
+
end
|
163
|
+
|
164
|
+
def modify_attributes(message, attributes = {})
|
165
|
+
attributes.each do |k,v|
|
166
|
+
A.inject(message, k, v)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def rename(message, id, newname)
|
171
|
+
message.set_attr 'id', id
|
172
|
+
message.set_attr 'newName', newname
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Doc Placeholder
|
179
|
+
class Parser
|
180
|
+
class << self
|
181
|
+
def get_all_response(class_name, response)
|
182
|
+
namespace = Zimbra::Base::NAMESPACES[class_name]
|
183
|
+
(response/"//n2:#{namespace}").map do |node|
|
184
|
+
response(class_name, node, false)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def response(class_name, node, full = true)
|
189
|
+
attrs = full ? get_attributes(node) : {}
|
190
|
+
id = (node/'@id').to_s
|
191
|
+
name = (node/'@name').to_s
|
192
|
+
|
193
|
+
object = Object.const_get "Zimbra::#{class_name}"
|
194
|
+
object.new(id, name, attrs, node)
|
195
|
+
end
|
196
|
+
|
197
|
+
# This method run over the children of the node
|
198
|
+
# and for each one gets the value of the n attribute
|
199
|
+
# "<a n=\"zimbraMailAlias\">restringida@zbox.cl</a>"
|
200
|
+
# would be zimbraMailAlias
|
201
|
+
def get_attributes_names(node)
|
202
|
+
(node/'n2:a').map { |e| (e/'@n').to_s }.uniq
|
203
|
+
end
|
204
|
+
|
205
|
+
def get_attributes(node)
|
206
|
+
attr_hash = {}
|
207
|
+
attributes = get_attributes_names node
|
208
|
+
attributes.each do |attr|
|
209
|
+
attr_hash[attr] = Zimbra::A.read node, attr
|
210
|
+
end
|
211
|
+
attr_hash
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|