VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/CloudUserProfilesImpl.cpp@ 73473

Last change on this file since 73473 was 73337, checked in by vboxsync, 7 years ago

bugref:9152. Renamed CloudUserProfileList to CloudUserProfiles.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.7 KB
Line 
1/* $Id: CloudUserProfilesImpl.cpp 73337 2018-07-23 22:05:26Z vboxsync $ */
2/** @file
3 * ICloudUserProfiles COM class implementations.
4 */
5
6/*
7 * Copyright (C) 2008-2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19#include <iprt/path.h>
20#include <iprt/cpp/utils.h>
21#include <VBox/com/array.h>
22
23#include "CloudUserProfilesImpl.h"
24#include "VirtualBoxImpl.h"
25#include "Global.h"
26#include "ProgressImpl.h"
27#include "MachineImpl.h"
28#include "AutoCaller.h"
29#include "Logging.h"
30
31using namespace std;
32
33////////////////////////////////////////////////////////////////////////////////
34//
35// SimpleConfigFile implementation
36//
37////////////////////////////////////////////////////////////////////////////////
38SimpleConfigFile::SimpleConfigFile(VirtualBoxBase *pSetError, const char *pszFilename)
39 : GeneralTextScript(pSetError, pszFilename)
40{
41 LogRel(("SimpleConfigFile::SimpleConfigFile(VirtualBoxBase *pSetError,...)\n"));
42}
43
44SimpleConfigFile::~SimpleConfigFile()
45{
46 LogRel(("SimpleConfigFile::~SimpleConfigFile()\n"));
47}
48
49HRESULT SimpleConfigFile::parse()
50{
51 LogRel(("Starting to parse the existing profiles\n"));
52 HRESULT hrc = S_OK;
53 hrc = GeneralTextScript::parse();
54 if (SUCCEEDED(hrc))
55 {
56 size_t lines = getLineNumbersOfScript();
57 LogRel(("Initial parsing (GeneralTextScript::parse()) was succeeded \n"));
58 LogRel(("Read lines is %d \n", lines));
59 size_t startSectionPos=0;
60 bool fInSection = false;
61 std::map <Utf8Str, Utf8Str> sectionConfiguration;
62 Utf8Str strSectionName("Default section ");
63
64 for (size_t i=0; i<lines; ++i)
65 {
66 //find the beginning of section, it starts from the line like "[section name]"
67 //next find the end of section, it ends up when we find the beginning
68 //of the next section or reach the end of the contents.
69 //Go through the found lines and split each of them up by "=".
70 //Each correct line must look like "key=value"
71 //if there is not the character "=" in the line one is skipped
72 //class Utf8Str contains the function parseKeyValue() for this action
73 LogRel(("Parsing the line %d \n", i));
74 Utf8Str strLineContent = getContentOfLine(i);
75 if (strLineContent.isEmpty() || strLineContent.startsWith("#"))
76 continue;
77
78 LogRel(("Content of the line %d is %s \n", i, strLineContent.c_str()));
79
80 //strips the white-space characters from the string. It's needed for strings on Windows with "\n\r".
81 strLineContent = strLineContent.strip();
82 if ( strLineContent.startsWith("[") && strLineContent.endsWith("]") )
83 {
84 LogRel(("Found section in the line %d\n", i));
85 if ( fInSection == true )
86 {
87 if ( i > startSectionPos )//at least we can have here 1 line in the section
88 {
89 LogRel(("Add section \"%s\" to the map \n", strSectionName.c_str()));
90 mSections.insert(make_pair(strSectionName, sectionConfiguration));
91 sectionConfiguration.clear();
92 strSectionName.append(Utf8StrFmt("%d",i).c_str());
93 }
94 }
95
96 strSectionName = strLineContent.substr(strLineContent.find("[")+1,
97 strLineContent.find("]")-1);
98 LogRel(("Section name is \"%s\" \n", strSectionName.c_str()));
99 fInSection = true;
100 startSectionPos = i+1;
101 }
102 else
103 {
104 if ( fInSection == true )
105 {
106 LogRel(("Continue to parse section \"%s\" \n", strSectionName.c_str()));
107 if ( i >= startSectionPos )
108 {
109 LogRel(("Extracting key and value:\n"));
110 Utf8Str key, value;
111 size_t offEnd = strLineContent.parseKeyValue(key, value);
112 if (offEnd == strLineContent.length())
113 {
114 LogRel(("%s=%s \n", key.c_str(), value.c_str()));
115 sectionConfiguration.insert(make_pair(key,value));
116 }
117 else
118 {
119 //else something goes wrong, skip the line
120 LogRel(("Coudn't extract key and value from the line %d\n", i));
121 }
122 }
123 }
124 else
125 {
126 LogRel(("Goes to the next line %d\n", i+1));
127 }
128 }
129 }
130
131 if (fInSection == false)//there is not any section
132 {
133 LogRel(("There are not any sections in the config\n"));
134 hrc = E_FAIL;
135 }
136 else //the last section hasn't a close tag (the close tag is just the beginning of next section)
137 {
138 //just insert the last section into the map
139 LogRel(("Add the last section %s to the map \n", strSectionName.c_str()));
140 mSections.insert(make_pair(strSectionName, sectionConfiguration));
141 }
142 }
143
144 return hrc;
145}
146
147HRESULT SimpleConfigFile::addSection(const Utf8Str &aSectionName, const std::map <Utf8Str, Utf8Str>& section)
148{
149 HRESULT hrc = S_OK;
150 if (aSectionName.isEmpty())
151 hrc = E_FAIL;
152 else
153 mSections.insert(make_pair(aSectionName, section));
154
155 return hrc;
156}
157
158std::vector <Utf8Str> SimpleConfigFile::getSectionsNames() const
159{
160 std::vector <Utf8Str> res;
161 std::map < Utf8Str, std::map <Utf8Str, Utf8Str> >::const_iterator cit = mSections.begin();
162 while (cit!=mSections.end())
163 {
164 res.push_back(cit->first);
165 ++cit;
166 }
167 return res;
168}
169
170std::map <Utf8Str, Utf8Str> SimpleConfigFile::getSectionByName (const Utf8Str &strSectionName) const
171{
172 std::map <Utf8Str, Utf8Str> res;
173 std::map < Utf8Str, std::map <Utf8Str, Utf8Str> >::const_iterator cit;
174 if ( (cit=mSections.find(strSectionName)) != mSections.end() )
175 {
176 res=cit->second;
177 }
178 return res;
179}
180
181HRESULT SimpleConfigFile::updateSection (const Utf8Str &strSectionName,
182 const std::map <Utf8Str, Utf8Str> &newSection)
183{
184 HRESULT hrc = S_OK;
185 std::map <Utf8Str, Utf8Str> oldSection = getSectionByName(strSectionName);
186 if (oldSection.empty())
187 {
188 //add new section
189 hrc = addSection(strSectionName, newSection);
190 }
191 else
192 {
193 //update old section by new values or add new pair key/value if there isn't such key
194 std::map <Utf8Str, Utf8Str>::const_iterator cit = newSection.begin();
195 while (cit != newSection.end())
196 {
197 oldSection[cit->first] = cit->second;
198 ++cit;
199 }
200
201 }
202 return hrc;
203}
204
205bool SimpleConfigFile::isSectionExist(const Utf8Str &strSectionName) const
206{
207 return ((mSections.find(strSectionName) == mSections.end()) ? false : true);
208}
209
210////////////////////////////////////////////////////////////////////////////////
211//
212// ICloudUserProfiles implementation
213//
214////////////////////////////////////////////////////////////////////////////////
215CloudUserProfiles::CloudUserProfiles()
216 : mParent(NULL)
217{
218}
219
220CloudUserProfiles::~CloudUserProfiles()
221{
222 LogRel(("CloudUserProfilesImpl::~CloudUserProfilesImpl()\n"));
223 unconst(mParent) = NULL;
224}
225
226HRESULT CloudUserProfiles::FinalConstruct()
227{
228 return BaseFinalConstruct();
229}
230
231void CloudUserProfiles::FinalRelease()
232{
233 uninit();
234
235 BaseFinalRelease();
236}
237
238void CloudUserProfiles::uninit()
239{
240 /* Enclose the state transition Ready->InUninit->NotReady */
241 AutoUninitSpan autoUninitSpan(this);
242 if (autoUninitSpan.uninitDone())
243 return;
244
245 unconst(mParent) = NULL;
246}
247
248HRESULT CloudUserProfiles::init(VirtualBox *aParent)
249{
250 /* Enclose the state transition NotReady->InInit->Ready */
251 AutoInitSpan autoInitSpan(this);
252 AssertReturn(autoInitSpan.isOk(), E_FAIL);
253
254 unconst(mParent) = aParent;
255
256 autoInitSpan.setSucceeded();
257 return S_OK;
258}
259
260
261HRESULT CloudUserProfiles::getSupportedPropertiesNames(std::vector<com::Utf8Str> &aPropertiesNames)
262{
263 LogRel(("CloudUserProfiles::getSupportedPropertiesNames:\n"));
264 aPropertiesNames.clear();
265 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
266}
267
268HRESULT CloudUserProfiles::readProfiles(const Utf8Str &strConfigPath)
269{
270 LogRel(("CloudUserProfiles::readProfiles: %s\n", strConfigPath.c_str()));
271 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
272}
273
274HRESULT CloudUserProfiles::getProvider(CloudProviderId_T *aProvider)
275{
276 *aProvider = CloudProviderId_Unknown;
277 LogRel(("CloudUserProfiles::getProvider: %d\n", *aProvider));
278 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
279}
280
281HRESULT CloudUserProfiles::createProfile(const com::Utf8Str &aProfileName,
282 const std::vector<com::Utf8Str> &aNames,
283 const std::vector<com::Utf8Str> &aValues)
284{
285 LogRel(("CloudUserProfiles::createProfile: %s, %d, %d\n", aProfileName.c_str(), aNames.size(), aValues.size()));
286 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
287}
288
289HRESULT CloudUserProfiles::updateProfile(const com::Utf8Str &aProfileName,
290 const std::vector<com::Utf8Str> &aNames,
291 const std::vector<com::Utf8Str> &aValues)
292{
293 LogRel(("CloudUserProfiles::updateProfile: %s, %d, %d\n", aProfileName.c_str(), aNames.size(), aValues.size()));
294 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
295}
296
297HRESULT CloudUserProfiles::getStoredProfilesNames(std::vector<com::Utf8Str> &aProfilesNames)
298{
299
300 LogRel(("CloudUserProfiles::getStoredProfilesNames:\n"));
301 aProfilesNames.clear();
302 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
303}
304
305HRESULT CloudUserProfiles::getProfileProperties(const com::Utf8Str &aProfileName,
306 std::vector<com::Utf8Str> &aReturnNames,
307 std::vector<com::Utf8Str> &aReturnValues)
308{
309 LogRel(("CloudUserProfiles::getProfileProperties: %s\n", aProfileName.c_str()));
310 aReturnNames.clear();
311 aReturnValues.clear();
312 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
313}
314
315HRESULT CloudUserProfiles::getPropertyDescription(const com::Utf8Str &aName,
316 com::Utf8Str &aDescription)
317{
318 LogRel(("CloudUserProfiles::getPropertyDescription: %s, %s\n", aName.c_str(), aDescription.c_str()));
319 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
320}
321
322HRESULT CloudUserProfiles::createCloudClient(const com::Utf8Str &aProfileName,
323 ComPtr<ICloudClient> &aCloudClient)
324{
325 LogRel(("CloudUserProfiles::createCloudClient: %s\n", aProfileName.c_str()));
326
327 if (aCloudClient.isNull())
328 {
329 LogRel(("aCloudClient is NULL\n"));
330 }
331
332 return setErrorBoth(E_FAIL, VERR_NOT_IMPLEMENTED, tr("Not implemented"));
333}
334
335////////////////////////////////////////////////////////////////////////////////
336//
337// CloudConnectionOCI implementation
338//
339////////////////////////////////////////////////////////////////////////////////
340static struct
341{
342 const char *pszOCIConfigEntry, *pszDesciption;
343} const g_aOCIConfigEntryToDescription[] =
344{
345 { "user", "OCID of the user calling the API." },
346 { "tenancy", "OCID of your tenancy." },
347 { "compartment", "OCID of your compartment." },
348 { "fingerprint", "Fingerprint for the key pair being used." },
349 { "key_file", "Full path and filename of the private key."
350 "If you encrypted the key with a passphrase, you must also include "
351 "the pass_phrase entry in the config file."},
352 { "pass_phrase", "Passphrase used for the key, if it is encrypted." },
353 { "region", "An Oracle Cloud Infrastructure region" },
354};
355
356
357OCIUserProfiles::OCIUserProfiles()
358{
359 LogRel(("OCIUserProfiles::OCIUserProfiles()\n"));
360 mpProfiles = new SimpleConfigFile(mParent);
361 LogRel(("Succeeded create SimpleConfigFile\n"));
362}
363
364OCIUserProfiles::~OCIUserProfiles()
365{
366 LogRel(("OCIUserProfiles::~OCIUserProfiles()\n"));
367 if (mpProfiles)
368 delete mpProfiles;
369}
370
371HRESULT OCIUserProfiles::createCloudClient(const com::Utf8Str &aProfileName,
372 ComPtr<ICloudClient> &aCloudClient)
373{
374 HRESULT hrc = S_OK;
375 CloudProviderId_T providerId;
376 hrc = getProvider(&providerId);
377
378 ComObjPtr<CloudClient> ptrCloudClient;
379 hrc = ptrCloudClient.createObject();
380 if (SUCCEEDED(hrc))
381 {
382 ComObjPtr<CloudClientOCI> ptrCloudClientOCI;
383 hrc = ptrCloudClientOCI.createObject();
384 AutoReadLock wlock(this COMMA_LOCKVAL_SRC_POS);
385 hrc = ptrCloudClientOCI->initCloudClient(this, mParent, providerId, aProfileName);
386 if (SUCCEEDED(hrc))
387 {
388 ptrCloudClient = ptrCloudClientOCI;
389 hrc = ptrCloudClient.queryInterfaceTo(aCloudClient.asOutParam());
390 }
391 }
392
393 return hrc;
394}
395
396HRESULT OCIUserProfiles::readProfiles(const Utf8Str &strConfigPath)
397{
398 LogRel(("Reading profiles from %s\n", strConfigPath.c_str()));
399 HRESULT hrc = S_OK;
400 if ( !strConfigPath.isEmpty() )
401 {
402 mStrConfigPath = strConfigPath;
403 hrc = mpProfiles->read(mStrConfigPath);
404 if (SUCCEEDED(hrc))
405 {
406 LogRel(("Successfully read the profiles from the config %s\n", mStrConfigPath.c_str()));
407 hrc = mpProfiles->parse();
408 if (FAILED(hrc))
409 {
410 return hrc;
411 }
412 LogRel(("Successfully parsed %d profiles\n", mpProfiles->getNumberOfSections()));
413 }
414 }
415 else
416 {
417 LogRel(("Empty path to config file\n"));
418 hrc = setErrorBoth(E_FAIL, VERR_INVALID_PARAMETER, tr("Empty path to config file"));
419 }
420
421 return hrc;
422}
423
424HRESULT OCIUserProfiles::createProfile(const com::Utf8Str &aProfileName,
425 const std::vector<com::Utf8Str> &aNames,
426 const std::vector<com::Utf8Str> &aValues)
427{
428 HRESULT hrc = S_OK;
429
430 if (!mpProfiles->isSectionExist(aProfileName))
431 {
432 std::map <Utf8Str, Utf8Str> newProfile;
433
434 for (size_t i=0;i<aNames.size();++i)
435 {
436 com::Utf8Str newValue = (i<aValues.size()) ? aValues.at(i) : "";
437 newProfile[aNames.at(i)] = newValue;
438 }
439
440 hrc = mpProfiles->addSection(aProfileName, newProfile);
441 }
442 else
443 hrc = setErrorBoth(E_FAIL, VERR_ALREADY_EXISTS, tr("Profile '%s' has already exested"), aProfileName.c_str());
444
445 return hrc;
446}
447
448HRESULT OCIUserProfiles::updateProfile(const com::Utf8Str &aProfileName,
449 const std::vector<com::Utf8Str> &aNames,
450 const std::vector<com::Utf8Str> &aValues)
451{
452 HRESULT hrc = S_OK;
453 if (mpProfiles->isSectionExist(aProfileName))
454 {
455 std::map <Utf8Str, Utf8Str> newProfile;
456
457 for (size_t i=0;i<aNames.size();++i)
458 {
459 com::Utf8Str newValue = (i<aValues.size()) ? aValues.at(i) : "";
460 newProfile[aNames.at(i)] = newValue;
461 }
462
463 hrc = mpProfiles->updateSection(aProfileName, newProfile);
464 }
465 else
466 hrc = setErrorBoth(E_FAIL, VERR_NOT_FOUND, tr("Profile '%s' wasn't found"), aProfileName.c_str());
467
468 return hrc;
469}
470
471HRESULT OCIUserProfiles::getStoredProfilesNames(std::vector<com::Utf8Str> &aProfilesNames)
472{
473 HRESULT hrc = S_OK;
474 aProfilesNames = mpProfiles->getSectionsNames();
475 if (aProfilesNames.empty())
476 hrc = setErrorBoth(E_FAIL, VERR_NOT_FOUND, tr("There aren't any profiles in the config"));
477
478 return hrc;
479}
480
481HRESULT OCIUserProfiles::getProfileProperties(const com::Utf8Str &aProfileName,
482 std::vector<com::Utf8Str> &aReturnNames,
483 std::vector<com::Utf8Str> &aReturnValues)
484{
485 HRESULT hrc = S_OK;
486
487 if (mpProfiles->isSectionExist(aProfileName))
488 {
489 std::map <Utf8Str, Utf8Str> profile;
490 hrc = i_getProfileProperties(aProfileName, profile);
491 if (SUCCEEDED(hrc))
492 {
493 aReturnNames.clear();
494 aReturnValues.clear();
495 std::map <Utf8Str, Utf8Str>::const_iterator cit = profile.begin();
496 while (cit!=profile.end())
497 {
498 aReturnNames.push_back(cit->first);
499 aReturnValues.push_back(cit->second);
500 ++cit;
501 }
502 }
503 }
504 else
505 hrc = setErrorBoth(E_FAIL, VERR_NOT_FOUND, tr("Profile '%s' wasn't found"), aProfileName.c_str());
506
507 return hrc;
508}
509
510HRESULT OCIUserProfiles::getSupportedPropertiesNames(std::vector<com::Utf8Str> &aPropertiesNames)
511{
512 HRESULT hrc = S_OK;
513 for (size_t i = 0; i < RT_ELEMENTS(g_aOCIConfigEntryToDescription); ++i)
514 aPropertiesNames.push_back(g_aOCIConfigEntryToDescription[i].pszOCIConfigEntry);
515 return hrc;
516}
517
518HRESULT OCIUserProfiles::getPropertyDescription(const com::Utf8Str &aName, com::Utf8Str &aDescription)
519{
520 HRESULT hrc = S_OK;
521 for (size_t i = 0; i < RT_ELEMENTS(g_aOCIConfigEntryToDescription); ++i)
522 if (aName.contains(g_aOCIConfigEntryToDescription[i].pszOCIConfigEntry, Utf8Str::CaseInsensitive))
523 {
524 aDescription = g_aOCIConfigEntryToDescription[i].pszDesciption;
525 }
526 return hrc;
527}
528
529
530HRESULT OCIUserProfiles::i_createProfile(const com::Utf8Str &aProfileName,
531 const std::map <Utf8Str, Utf8Str> &aProfile)
532{
533 HRESULT hrc = S_OK;
534
535 hrc = mpProfiles->addSection(aProfileName, aProfile);
536
537 return hrc;
538}
539
540HRESULT OCIUserProfiles::i_updateProfile(const com::Utf8Str &aProfileName,
541 const std::map <Utf8Str, Utf8Str> &aProfile)
542{
543 HRESULT hrc = S_OK;
544 if (mpProfiles->isSectionExist(aProfileName))
545 hrc = mpProfiles->updateSection(aProfileName, aProfile);
546 else
547 hrc = setErrorBoth(E_FAIL, VERR_NOT_FOUND, tr("Profile '%s' wasn't found"), aProfileName.c_str());
548
549
550 return hrc;
551}
552
553HRESULT OCIUserProfiles::i_getProfileProperties(const com::Utf8Str &aProfileName,
554 std::map <Utf8Str, Utf8Str> &aProfile)
555{
556 HRESULT hrc = S_OK;
557 std::map <Utf8Str, Utf8Str> defProfile = mpProfiles->getSectionByName("DEFAULT");
558 std::map <Utf8Str, Utf8Str> reqProfile = mpProfiles->getSectionByName(aProfileName);
559
560 std::map <Utf8Str, Utf8Str>::iterator itDefProfile = defProfile.begin();
561 while (itDefProfile != defProfile.end())
562 {
563 std::map <Utf8Str, Utf8Str>::iterator itProfile = reqProfile.find(itDefProfile->first);
564 if (itProfile == reqProfile.end())
565 {
566 //Add a key=value pair from defProfile into the reqProfile if the key doesn't exist in the reqProfile.
567 reqProfile.insert(*itDefProfile);
568 }
569 ++itDefProfile;
570 }
571
572 if (!reqProfile.empty())
573 aProfile = reqProfile;
574 else
575 hrc = setErrorBoth(E_FAIL, VERR_NOT_FOUND, tr("Profile '%s' wasn't found"), aProfileName.c_str());
576
577 return hrc;
578}
579
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette