/mojomail/imap/src/data/ImapAccountAdapter.cpp
C++ | 270 lines | 182 code | 50 blank | 38 comment | 18 complexity | 6dd0775ae6e7272757568c9604011618 MD5 | raw file
1// @@@LICENSE
2//
3// Copyright (c) 2010-2012 Hewlett-Packard Development Company, L.P.
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
17// LICENSE@@@
18
19#include "data/ImapAccountAdapter.h"
20#include "data/DatabaseAdapter.h"
21#include "data/EmailAccountAdapter.h"
22#include "ImapCoreDefs.h"
23#include "ImapConfig.h"
24
25using namespace std;
26
27const char* const ImapAccountAdapter::KIND = "_kind";
28const char* const ImapAccountAdapter::SYNCKEY = "syncKey";
29const char* const ImapAccountAdapter::ID = "_id";
30const char* const ImapAccountAdapter::TEMPLATEID = "templateId";
31const char* const ImapAccountAdapter::ACCOUNT_ID = "accountId";
32const char* const ImapAccountAdapter::REV = "_rev";
33
34const char* const ImapAccountAdapter::CONFIG_REV = "ImapConfigRev";
35
36const char* const ImapAccountAdapter::SCHEMA = "com.palm.imap.account:1";
37const char* const ImapAccountAdapter::USERNAME = "username";
38const char* const ImapAccountAdapter::EMAIL = "email";
39const char* const ImapAccountAdapter::HOSTNAME = "server";
40const char* const ImapAccountAdapter::PORT = "port";
41const char* const ImapAccountAdapter::ENCRYPTION = "encryption";
42const char* const ImapAccountAdapter::CONFIG = "config";
43
44const char* const ImapAccountAdapter::NO_SSL = "none";
45const char* const ImapAccountAdapter::REQUIRE_SSL = "ssl";
46const char* const ImapAccountAdapter::TLS = "tls";
47const char* const ImapAccountAdapter::TLS_IF_AVAILABLE = "tlsIfAvailable";
48
49// IMAP-specific
50const char* const ImapAccountAdapter::ROOT_FOLDER = "rootFolder";
51
52// Compatibility options
53const char* const ImapAccountAdapter::ENABLE_COMPRESS = "enableCompress";
54const char* const ImapAccountAdapter::ENABLE_EXPUNGE = "enableExpunge";
55
56const int ImapAccountAdapter::DEFAULT_SYNC_FREQUENCY_MINS = -1; // push
57const int ImapAccountAdapter::DEFAULT_SYNC_WINDOW_DAYS = 7; // one week
58
59/**
60 * Parse two database objects into an ImapAccount
61 *
62 * @param in com.palm.mail.account database object
63 * @param transportIn com.palm.imap.account database object
64 * @param out ImapAccount
65 */
66void ImapAccountAdapter::GetImapAccount(const MojObject& in, const MojObject& transportIn, ImapAccount& out)
67{
68 MojObject id;
69 MojErr err = in.getRequired(ID, id);
70 ErrorToException(err);
71 out.SetId(id);
72
73 // Template from account object
74 MojString templateId;
75 bool hasTemplateId = false;
76 err = in.get(TEMPLATEID, templateId, hasTemplateId); // make required later
77 ErrorToException(err);
78 if(hasTemplateId)
79 {
80 out.SetTemplateId(templateId.data());
81 }
82
83 boost::shared_ptr<ImapLoginSettings> loginSettings(new ImapLoginSettings());
84
85 // Username from account object (this is always the email address)
86 MojString username;
87 in.getRequired(USERNAME, username);
88 ErrorToException(err);
89
90 loginSettings->SetUsername(username.data());
91
92 // Read server settings
93 ParseLoginConfig(transportIn, *loginSettings);
94
95 // Store updated server settings on account
96 out.SetLoginSettings(loginSettings);
97
98 int syncFrequencyMin;
99 err = transportIn.getRequired(EmailAccountAdapter::SYNC_FREQUENCY_MINS, syncFrequencyMin);
100 ErrorToException(err);
101 out.SetSyncFrequencyMins(syncFrequencyMin);
102
103 int syncWindowDays;
104 err = transportIn.getRequired(EmailAccountAdapter::SYNC_WINDOW_DAYS, syncWindowDays);
105 ErrorToException(err);
106 out.SetSyncWindowDays(syncWindowDays);
107
108 MojInt64 rev;
109 err = transportIn.getRequired(REV, rev);
110 ErrorToException(err);
111 out.SetRevision(rev);
112
113 // Retrieve the optional error status
114 MojObject errorObj;
115 if(transportIn.get(EmailAccountAdapter::ERROR, errorObj))
116 {
117 EmailAccount::AccountError accountError;
118 EmailAccountAdapter::ParseErrorInfo(errorObj, accountError);
119
120 out.SetError(accountError);
121 }
122
123 // Compatibility/workaround options
124 bool enableCompress = DatabaseAdapter::GetOptionalBool(transportIn, ENABLE_COMPRESS, ImapConfig::GetConfig().GetEnableCompress());
125 bool enableExpunge = DatabaseAdapter::GetOptionalBool(transportIn, ENABLE_EXPUNGE, true);
126
127 out.SetEnableCompression(enableCompress);
128 out.SetEnableExpunge(enableExpunge);
129
130 // Read special folders
131 EmailAccountAdapter::ParseSpecialFolders(transportIn, out);
132
133 // Read retry status
134 EmailAccountAdapter::ParseAccountRetryStatus(transportIn, out);
135
136 // Root folder prefix
137 bool hasRootFolder = false;
138 MojString rootFolder;
139 err = transportIn.get(ROOT_FOLDER, rootFolder, hasRootFolder);
140 ErrorToException(err);
141
142 if(hasRootFolder) {
143 out.SetNamespaceRoot( string(rootFolder.data()) );
144 }
145}
146
147ImapLoginSettings::EncryptionType ImapAccountAdapter::GetEncryptionType(const MojString& encryptionStr)
148{
149 if (encryptionStr == NO_SSL)
150 return ImapLoginSettings::Encrypt_None;
151 else if(encryptionStr == REQUIRE_SSL)
152 return ImapLoginSettings::Encrypt_SSL;
153 else if(encryptionStr == TLS)
154 return ImapLoginSettings::Encrypt_TLS;
155 else if(encryptionStr == TLS_IF_AVAILABLE)
156 return ImapLoginSettings::Encrypt_TLSIfAvailable;
157 else {
158 throw MailException("unknown/invalid ssl encryption type", __FILE__, __LINE__);
159 }
160}
161
162// Copy fields from createAccount payload into com.palm.imap.account object
163void ImapAccountAdapter::GetImapAccountFromPayload(const MojObject& accountObj, const MojObject& payload, MojObject& imapAccount)
164{
165 MojErr err = imapAccount.putString(ImapAccountAdapter::KIND, ImapAccountAdapter::SCHEMA);
166 ErrorToException(err);
167
168 MojObject accountId;
169 err = payload.getRequired(ImapAccountAdapter::ACCOUNT_ID, accountId);
170 ErrorToException(err);
171
172 err = imapAccount.put(ImapAccountAdapter::ACCOUNT_ID, accountId);
173 ErrorToException(err);
174
175 MojObject config;
176 err = payload.getRequired(ImapAccountAdapter::CONFIG, config);
177 ErrorToException(err);
178
179 MojString username;
180 bool hasUsername = false;
181 err = config.get(ImapAccountAdapter::USERNAME, username, hasUsername);
182 ErrorToException(err);
183 if(!hasUsername)
184 {
185 err = accountObj.getRequired(ImapAccountAdapter::USERNAME, username);
186 ErrorToException(err);
187 }
188 err = imapAccount.put(ImapAccountAdapter::USERNAME, username);
189 ErrorToException(err);
190
191 MojString hostname;
192 err = config.getRequired(ImapAccountAdapter::HOSTNAME, hostname);
193 ErrorToException(err);
194
195 err = imapAccount.put(ImapAccountAdapter::HOSTNAME, hostname);
196 ErrorToException(err);
197
198 int port;
199 err = config.getRequired(ImapAccountAdapter::PORT, port);
200 ErrorToException(err);
201
202 err = imapAccount.put(ImapAccountAdapter::PORT, port);
203 ErrorToException(err);
204
205 MojString encryption;
206 err = config.getRequired(ImapAccountAdapter::ENCRYPTION, encryption);
207 ErrorToException(err);
208
209 err = imapAccount.put(ImapAccountAdapter::ENCRYPTION, encryption);
210 ErrorToException(err);
211
212 /* Optional config parameters; fill in with defaults if not provided */
213
214 bool hasSyncFrequency = false;
215 int syncFrequencyMins = 0;
216 config.get(EmailAccountAdapter::SYNC_FREQUENCY_MINS, syncFrequencyMins, hasSyncFrequency);
217 ErrorToException(err);
218
219 err = imapAccount.putInt(EmailAccountAdapter::SYNC_FREQUENCY_MINS,
220 hasSyncFrequency ? syncFrequencyMins : DEFAULT_SYNC_FREQUENCY_MINS);
221 ErrorToException(err);
222
223 bool hasSyncWindow = false;
224 int syncWindow = 0;
225 err = config.get(EmailAccountAdapter::SYNC_WINDOW_DAYS, syncWindow, hasSyncWindow);
226 ErrorToException(err);
227
228 err = imapAccount.putInt(EmailAccountAdapter::SYNC_WINDOW_DAYS,
229 hasSyncWindow ? syncWindow : DEFAULT_SYNC_WINDOW_DAYS);
230 ErrorToException(err);
231}
232
233MojObject ImapAccountAdapter::GetFolderId(const MojObject& obj, const char* prop)
234{
235 MojObject folderId(MojObject::Undefined);
236 if(obj.contains(prop)) {
237 MojErr err = obj.getRequired(prop, folderId);
238 ErrorToException(err);
239 }
240 return folderId;
241}
242
243void ImapAccountAdapter::ParseLoginConfig(const MojObject& config, ImapLoginSettings& login)
244{
245 MojErr err;
246
247 // Optional username; overrides account username if available
248 bool hasServerUsername = false;
249 MojString serverUsername;
250 err = config.get(ImapAccountAdapter::USERNAME, serverUsername, hasServerUsername);
251 ErrorToException(err);
252 if(hasServerUsername) {
253 login.SetUsername(serverUsername.data());
254 }
255
256 MojString hostname;
257 err = config.getRequired(ImapAccountAdapter::HOSTNAME, hostname);
258 ErrorToException(err);
259 login.SetHostname(hostname.data());
260
261 int port;
262 err = config.getRequired(ImapAccountAdapter::PORT, port);
263 ErrorToException(err);
264 login.SetPort(port);
265
266 MojString encryptionStr;
267 err = config.getRequired(ImapAccountAdapter::ENCRYPTION, encryptionStr);
268 ErrorToException(err);
269 login.SetEncryption(GetEncryptionType(encryptionStr));
270}