1 /*
2 * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
3 *
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6
7 #include "CredentialsStorage.h"
8
9 #include <new>
10 #include <stdio.h>
11
12 #include <Autolock.h>
13 #include <Entry.h>
14 #include <File.h>
15 #include <FindDirectory.h>
16 #include <Message.h>
17 #include <Path.h>
18
19 #include "BrowserApp.h"
20
21
Credentials()22 Credentials::Credentials()
23 :
24 fUsername(),
25 fPassword()
26 {
27 }
28
29
Credentials(const BString & username,const BString & password)30 Credentials::Credentials(const BString& username, const BString& password)
31 :
32 fUsername(username),
33 fPassword(password)
34 {
35 }
36
37
Credentials(const Credentials & other)38 Credentials::Credentials(const Credentials& other)
39 {
40 *this = other;
41 }
42
43
Credentials(const BMessage * archive)44 Credentials::Credentials(const BMessage* archive)
45 {
46 if (archive == NULL)
47 return;
48 archive->FindString("username", &fUsername);
49 archive->FindString("password", &fPassword);
50 }
51
52
~Credentials()53 Credentials::~Credentials()
54 {
55 }
56
57
58 status_t
Archive(BMessage * archive) const59 Credentials::Archive(BMessage* archive) const
60 {
61 if (archive == NULL)
62 return B_BAD_VALUE;
63 status_t status = archive->AddString("username", fUsername);
64 if (status == B_OK)
65 status = archive->AddString("password", fPassword);
66 return status;
67 }
68
69
70 Credentials&
operator =(const Credentials & other)71 Credentials::operator=(const Credentials& other)
72 {
73 if (this == &other)
74 return *this;
75
76 fUsername = other.fUsername;
77 fPassword = other.fPassword;
78
79 return *this;
80 }
81
82
83 bool
operator ==(const Credentials & other) const84 Credentials::operator==(const Credentials& other) const
85 {
86 if (this == &other)
87 return true;
88
89 return fUsername == other.fUsername && fPassword == other.fPassword;
90 }
91
92
93 bool
operator !=(const Credentials & other) const94 Credentials::operator!=(const Credentials& other) const
95 {
96 return !(*this == other);
97 }
98
99
100 const BString&
Username() const101 Credentials::Username() const
102 {
103 return fUsername;
104 }
105
106
107 const BString&
Password() const108 Credentials::Password() const
109 {
110 return fPassword;
111 }
112
113
114 // #pragma mark - CredentialsStorage
115
116
117 CredentialsStorage
118 CredentialsStorage::sPersistentInstance(true);
119
120
121 CredentialsStorage
122 CredentialsStorage::sSessionInstance(false);
123
124
CredentialsStorage(bool persistent)125 CredentialsStorage::CredentialsStorage(bool persistent)
126 :
127 BLocker(persistent ? "persistent credential storage"
128 : "credential storage"),
129 fCredentialMap(),
130 fSettingsLoaded(false),
131 fPersistent(persistent)
132 {
133 }
134
135
~CredentialsStorage()136 CredentialsStorage::~CredentialsStorage()
137 {
138 _SaveSettings();
139 }
140
141
142 /*static*/ CredentialsStorage*
SessionInstance()143 CredentialsStorage::SessionInstance()
144 {
145 return &sSessionInstance;
146 }
147
148
149 /*static*/ CredentialsStorage*
PersistentInstance()150 CredentialsStorage::PersistentInstance()
151 {
152 if (sPersistentInstance.Lock()) {
153 sPersistentInstance._LoadSettings();
154 sPersistentInstance.Unlock();
155 }
156 return &sPersistentInstance;
157 }
158
159
160 bool
Contains(const HashString & key)161 CredentialsStorage::Contains(const HashString& key)
162 {
163 BAutolock _(this);
164
165 return fCredentialMap.ContainsKey(key);
166 }
167
168
169 status_t
PutCredentials(const HashString & key,const Credentials & credentials)170 CredentialsStorage::PutCredentials(const HashString& key,
171 const Credentials& credentials)
172 {
173 BAutolock _(this);
174
175 return fCredentialMap.Put(key, credentials);
176 }
177
178
179 Credentials
GetCredentials(const HashString & key)180 CredentialsStorage::GetCredentials(const HashString& key)
181 {
182 BAutolock _(this);
183
184 return fCredentialMap.Get(key);
185 }
186
187
188 // #pragma mark - private
189
190
191 void
_LoadSettings()192 CredentialsStorage::_LoadSettings()
193 {
194 if (!fPersistent || fSettingsLoaded)
195 return;
196
197 fSettingsLoaded = true;
198
199 BFile settingsFile;
200 if (_OpenSettingsFile(settingsFile, B_READ_ONLY)) {
201 BMessage settingsArchive;
202 settingsArchive.Unflatten(&settingsFile);
203 BMessage credentialsArchive;
204 for (int32 i = 0; settingsArchive.FindMessage("credentials", i,
205 &credentialsArchive) == B_OK; i++) {
206 BString key;
207 if (credentialsArchive.FindString("key", &key) == B_OK) {
208 Credentials credentials(&credentialsArchive);
209 fCredentialMap.Put(key.String(), credentials);
210 }
211 }
212 }
213 }
214
215
216 void
_SaveSettings() const217 CredentialsStorage::_SaveSettings() const
218 {
219 BFile settingsFile;
220 if (_OpenSettingsFile(settingsFile,
221 B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY)) {
222 BMessage settingsArchive;
223 BMessage credentialsArchive;
224 CredentialMap::Iterator iterator = fCredentialMap.GetIterator();
225 while (iterator.HasNext()) {
226 const CredentialMap::Entry& entry = iterator.Next();
227 if (entry.value.Archive(&credentialsArchive) != B_OK
228 || credentialsArchive.AddString("key",
229 entry.key.GetString()) != B_OK) {
230 break;
231 }
232 if (settingsArchive.AddMessage("credentials",
233 &credentialsArchive) != B_OK) {
234 break;
235 }
236 credentialsArchive.MakeEmpty();
237 }
238 settingsArchive.Flatten(&settingsFile);
239 }
240 }
241
242
243 bool
_OpenSettingsFile(BFile & file,uint32 mode) const244 CredentialsStorage::_OpenSettingsFile(BFile& file, uint32 mode) const
245 {
246 BPath path;
247 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
248 || path.Append(kApplicationName) != B_OK
249 || path.Append("CredentialsStorage") != B_OK) {
250 return false;
251 }
252 return file.SetTo(path.Path(), mode) == B_OK;
253 }
254
255