xref: /haiku/src/apps/webpositive/CredentialsStorage.cpp (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
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 
22 Credentials::Credentials()
23 	:
24 	fUsername(),
25 	fPassword()
26 {
27 }
28 
29 
30 Credentials::Credentials(const BString& username, const BString& password)
31 	:
32 	fUsername(username),
33 	fPassword(password)
34 {
35 }
36 
37 
38 Credentials::Credentials(const Credentials& other)
39 {
40 	*this = other;
41 }
42 
43 
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 
53 Credentials::~Credentials()
54 {
55 }
56 
57 
58 status_t
59 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&
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
84 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
94 Credentials::operator!=(const Credentials& other) const
95 {
96 	return !(*this == other);
97 }
98 
99 
100 const BString&
101 Credentials::Username() const
102 {
103 	return fUsername;
104 }
105 
106 
107 const BString&
108 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 
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 
136 CredentialsStorage::~CredentialsStorage()
137 {
138 	_SaveSettings();
139 }
140 
141 
142 /*static*/ CredentialsStorage*
143 CredentialsStorage::SessionInstance()
144 {
145 	return &sSessionInstance;
146 }
147 
148 
149 /*static*/ CredentialsStorage*
150 CredentialsStorage::PersistentInstance()
151 {
152 	if (sPersistentInstance.Lock()) {
153 		sPersistentInstance._LoadSettings();
154 		sPersistentInstance.Unlock();
155 	}
156 	return &sPersistentInstance;
157 }
158 
159 
160 bool
161 CredentialsStorage::Contains(const HashString& key)
162 {
163 	BAutolock _(this);
164 
165 	return fCredentialMap.ContainsKey(key);
166 }
167 
168 
169 status_t
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
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
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
217 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
244 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