[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / PasswordManager.cpp
blobfdbb902afcc16eba43e3910a3a8f6f5c27a83e8a
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "PasswordManager.h"
11 #include "ServiceBroker.h"
12 #include "URL.h"
13 #include "profiles/ProfileManager.h"
14 #include "profiles/dialogs/GUIDialogLockSettings.h"
15 #include "settings/SettingsComponent.h"
16 #include "utils/FileUtils.h"
17 #include "utils/StringUtils.h"
18 #include "utils/XMLUtils.h"
19 #include "utils/log.h"
21 #include <mutex>
23 CPasswordManager &CPasswordManager::GetInstance()
25 static CPasswordManager sPasswordManager;
26 return sPasswordManager;
29 CPasswordManager::CPasswordManager()
31 m_loaded = false;
34 bool CPasswordManager::AuthenticateURL(CURL &url)
36 std::unique_lock<CCriticalSection> lock(m_critSection);
38 if (!m_loaded)
39 Load();
40 std::string lookup(GetLookupPath(url));
41 std::map<std::string, std::string>::const_iterator it = m_temporaryCache.find(lookup);
42 if (it == m_temporaryCache.end())
43 { // second step, try something that doesn't quite match
44 it = m_temporaryCache.find(GetServerLookup(lookup));
46 if (it != m_temporaryCache.end())
48 CURL auth(it->second);
49 url.SetDomain(auth.GetDomain());
50 url.SetPassword(auth.GetPassWord());
51 url.SetUserName(auth.GetUserName());
52 return true;
54 return false;
57 bool CPasswordManager::PromptToAuthenticateURL(CURL &url)
59 std::unique_lock<CCriticalSection> lock(m_critSection);
61 std::string passcode;
62 std::string username = url.GetUserName();
63 std::string domain = url.GetDomain();
64 if (!domain.empty())
65 username = domain + '\\' + username;
67 bool saveDetails = false;
68 if (!CGUIDialogLockSettings::ShowAndGetUserAndPassword(username, passcode, url.GetWithoutUserDetails(), &saveDetails))
69 return false;
71 // domain/name to domain\name
72 std::string name = username;
73 std::replace(name.begin(), name.end(), '/', '\\');
75 if (url.IsProtocol("smb") && name.find('\\') != std::string::npos)
77 auto pair = StringUtils::Split(name, '\\', 2);
78 url.SetDomain(pair[0]);
79 url.SetUserName(pair[1]);
81 else
83 url.SetDomain("");
84 url.SetUserName(username);
87 url.SetPassword(passcode);
89 // save the information for later
90 SaveAuthenticatedURL(url, saveDetails);
91 return true;
94 void CPasswordManager::SaveAuthenticatedURL(const CURL &url, bool saveToProfile)
96 // don't store/save authenticated url if it doesn't contain username
97 if (url.GetUserName().empty())
98 return;
100 std::unique_lock<CCriticalSection> lock(m_critSection);
102 std::string path = GetLookupPath(url);
103 std::string authenticatedPath = url.Get();
105 if (!m_loaded)
106 Load();
108 if (saveToProfile)
109 { // write to some random XML file...
110 m_permanentCache[path] = authenticatedPath;
111 Save();
114 // save for both this path and more generally the server as a whole.
115 m_temporaryCache[path] = authenticatedPath;
116 m_temporaryCache[GetServerLookup(path)] = authenticatedPath;
119 bool CPasswordManager::IsURLSupported(const CURL &url)
121 return url.IsProtocol("smb")
122 || url.IsProtocol("nfs")
123 || url.IsProtocol("ftp")
124 || url.IsProtocol("ftps")
125 || url.IsProtocol("sftp")
126 || url.IsProtocol("http")
127 || url.IsProtocol("https")
128 || url.IsProtocol("dav")
129 || url.IsProtocol("davs");
132 void CPasswordManager::Clear()
134 m_temporaryCache.clear();
135 m_permanentCache.clear();
136 m_loaded = false;
139 void CPasswordManager::Load()
141 Clear();
143 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
145 std::string passwordsFile = profileManager->GetUserDataItem("passwords.xml");
146 if (CFileUtils::Exists(passwordsFile))
148 CXBMCTinyXML doc;
149 if (!doc.LoadFile(passwordsFile))
151 CLog::Log(LOGERROR, "{} - Unable to load: {}, Line {}\n{}", __FUNCTION__, passwordsFile,
152 doc.ErrorRow(), doc.ErrorDesc());
153 return;
155 const TiXmlElement *root = doc.RootElement();
156 if (root->ValueStr() != "passwords")
157 return;
158 // read in our passwords
159 const TiXmlElement *path = root->FirstChildElement("path");
160 while (path)
162 std::string from, to;
163 if (XMLUtils::GetPath(path, "from", from) && XMLUtils::GetPath(path, "to", to))
165 m_permanentCache[from] = to;
166 m_temporaryCache[from] = to;
167 m_temporaryCache[GetServerLookup(from)] = to;
169 path = path->NextSiblingElement("path");
172 m_loaded = true;
175 void CPasswordManager::Save() const
177 if (m_permanentCache.empty())
178 return;
180 CXBMCTinyXML doc;
181 TiXmlElement rootElement("passwords");
182 TiXmlNode *root = doc.InsertEndChild(rootElement);
183 if (!root)
184 return;
186 for (std::map<std::string, std::string>::const_iterator i = m_permanentCache.begin(); i != m_permanentCache.end(); ++i)
188 TiXmlElement pathElement("path");
189 TiXmlNode *path = root->InsertEndChild(pathElement);
190 XMLUtils::SetPath(path, "from", i->first);
191 XMLUtils::SetPath(path, "to", i->second);
194 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
196 doc.SaveFile(profileManager->GetUserDataItem("passwords.xml"));
199 std::string CPasswordManager::GetLookupPath(const CURL &url) const
201 if (url.IsProtocol("sftp"))
202 return GetServerLookup(url.Get());
204 return url.GetProtocol() + "://" + url.GetHostName() + "/" + url.GetShareName();
207 std::string CPasswordManager::GetServerLookup(const std::string &path) const
209 CURL url(path);
210 return url.GetProtocol() + "://" + url.GetHostName() + "/";