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 22Credentials::Credentials() 23 : 24 fUsername(), 25 fPassword() 26{ 27} 28 29 30Credentials::Credentials(const BString& username, const BString& password) 31 : 32 fUsername(username), 33 fPassword(password) 34{ 35} 36 37 38Credentials::Credentials(const Credentials& other) 39{ 40 *this = other; 41} 42 43 44Credentials::Credentials(const BMessage* archive) 45{ 46 if (archive == NULL) 47 return; 48 archive->FindString("username", &fUsername); 49 archive->FindString("password", &fPassword); 50} 51 52 53Credentials::~Credentials() 54{ 55} 56 57 58status_t 59Credentials::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 70Credentials& 71Credentials::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 83bool 84Credentials::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 93bool 94Credentials::operator!=(const Credentials& other) const 95{ 96 return !(*this == other); 97} 98 99 100const BString& 101Credentials::Username() const 102{ 103 return fUsername; 104} 105 106 107const BString& 108Credentials::Password() const 109{ 110 return fPassword; 111} 112 113 114// #pragma mark - CredentialsStorage 115 116 117CredentialsStorage 118CredentialsStorage::sPersistentInstance(true); 119 120 121CredentialsStorage 122CredentialsStorage::sSessionInstance(false); 123 124 125CredentialsStorage::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 136CredentialsStorage::~CredentialsStorage() 137{ 138 _SaveSettings(); 139} 140 141 142/*static*/ CredentialsStorage* 143CredentialsStorage::SessionInstance() 144{ 145 return &sSessionInstance; 146} 147 148 149/*static*/ CredentialsStorage* 150CredentialsStorage::PersistentInstance() 151{ 152 if (sPersistentInstance.Lock()) { 153 sPersistentInstance._LoadSettings(); 154 sPersistentInstance.Unlock(); 155 } 156 return &sPersistentInstance; 157} 158 159 160bool 161CredentialsStorage::Contains(const HashKeyString& key) 162{ 163 BAutolock _(this); 164 165 return fCredentialMap.ContainsKey(key); 166} 167 168 169status_t 170CredentialsStorage::PutCredentials(const HashKeyString& key, 171 const Credentials& credentials) 172{ 173 BAutolock _(this); 174 175 return fCredentialMap.Put(key, credentials); 176} 177 178 179Credentials 180CredentialsStorage::GetCredentials(const HashKeyString& key) 181{ 182 BAutolock _(this); 183 184 return fCredentialMap.Get(key); 185} 186 187 188// #pragma mark - private 189 190 191void 192CredentialsStorage::_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, credentials); 210 } 211 } 212 } 213} 214 215 216void 217CredentialsStorage::_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.value) != 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 243bool 244CredentialsStorage::_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