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