1 /*
2 * Copyright (C) 2013-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "ProfilesOperations.h"
10
11 #include "GUIPassword.h"
12 #include "ServiceBroker.h"
13 #include "guilib/LocalizeStrings.h"
14 #include "messaging/ApplicationMessenger.h"
15 #include "profiles/ProfileManager.h"
16 #include "settings/SettingsComponent.h"
17 #include "utils/Digest.h"
18 #include "utils/Variant.h"
19
20 using namespace JSONRPC;
21 using namespace KODI::MESSAGING;
22 using KODI::UTILITY::CDigest;
23
GetProfiles(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)24 JSONRPC_STATUS CProfilesOperations::GetProfiles(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
25 {
26 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
27
28 CFileItemList listItems;
29
30 for (unsigned int i = 0; i < profileManager->GetNumberOfProfiles(); ++i)
31 {
32 const CProfile *profile = profileManager->GetProfile(i);
33 CFileItemPtr item(new CFileItem(profile->getName()));
34 item->SetArt("thumb", profile->getThumb());
35 listItems.Add(item);
36 }
37
38 HandleFileItemList("profileid", false, "profiles", listItems, parameterObject, result);
39
40 for (CVariant::const_iterator_array propertyiter = parameterObject["properties"].begin_array(); propertyiter != parameterObject["properties"].end_array(); ++propertyiter)
41 {
42 if (propertyiter->isString() &&
43 propertyiter->asString() == "lockmode")
44 {
45 for (CVariant::iterator_array profileiter = result["profiles"].begin_array(); profileiter != result["profiles"].end_array(); ++profileiter)
46 {
47 std::string profilename = (*profileiter)["label"].asString();
48 int index = profileManager->GetProfileIndex(profilename);
49 const CProfile *profile = profileManager->GetProfile(index);
50 LockType locktype = LOCK_MODE_UNKNOWN;
51 if (index == 0)
52 locktype = profileManager->GetMasterProfile().getLockMode();
53 else
54 locktype = profile->getLockMode();
55 (*profileiter)["lockmode"] = locktype;
56 }
57 break;
58 }
59 }
60 return OK;
61 }
62
GetCurrentProfile(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)63 JSONRPC_STATUS CProfilesOperations::GetCurrentProfile(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
64 {
65 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
66
67 const CProfile& currentProfile = profileManager->GetCurrentProfile();
68 CVariant profileVariant = CVariant(CVariant::VariantTypeObject);
69 profileVariant["label"] = currentProfile.getName();
70 for (CVariant::const_iterator_array propertyiter = parameterObject["properties"].begin_array(); propertyiter != parameterObject["properties"].end_array(); ++propertyiter)
71 {
72 if (propertyiter->isString())
73 {
74 if (propertyiter->asString() == "lockmode")
75 profileVariant["lockmode"] = currentProfile.getLockMode();
76 else if (propertyiter->asString() == "thumbnail")
77 profileVariant["thumbnail"] = currentProfile.getThumb();
78 }
79 }
80
81 result = profileVariant;
82
83 return OK;
84 }
85
LoadProfile(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)86 JSONRPC_STATUS CProfilesOperations::LoadProfile(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result)
87 {
88 const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager();
89
90 std::string profilename = parameterObject["profile"].asString();
91 int index = profileManager->GetProfileIndex(profilename);
92
93 if (index < 0)
94 return InvalidParams;
95
96 // get the profile
97 const CProfile *profile = profileManager->GetProfile(index);
98 if (profile == NULL)
99 return InvalidParams;
100
101 bool bPrompt = parameterObject["prompt"].asBoolean();
102 bool bCanceled = false;
103 bool bLoadProfile = false;
104
105 // if the profile does not require a password or
106 // the user is prompted and provides the correct password
107 // we can load the requested profile
108 if (profile->getLockMode() == LOCK_MODE_EVERYONE ||
109 (bPrompt && g_passwordManager.IsProfileLockUnlocked(index, bCanceled, bPrompt)))
110 bLoadProfile = true;
111 else if (!bCanceled) // Password needed and user provided it
112 {
113 const CVariant &passwordObject = parameterObject["password"];
114 const std::string& strToVerify = profile->getLockCode();
115 std::string password = passwordObject["value"].asString();
116
117 // Create password hash from the provided password if md5 is not used
118 std::string md5pword2;
119 std::string encryption = passwordObject["encryption"].asString();
120 if (encryption == "none")
121 md5pword2 = CDigest::Calculate(CDigest::Type::MD5, password);
122 else if (encryption == "md5")
123 md5pword2 = password;
124
125 // Verify provided password
126 if (StringUtils::EqualsNoCase(strToVerify, md5pword2))
127 bLoadProfile = true;
128 }
129
130 if (bLoadProfile)
131 {
132 CApplicationMessenger::GetInstance().PostMsg(TMSG_LOADPROFILE, index);
133 return ACK;
134 }
135 return InvalidParams;
136 }
137