VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/CloudUserProfileListImpl.cpp@ 73218

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

CloudUserProfileManager::getProfilesByProvider: Use IPRT for building paths correctly. Pointed out a whole bunch of error code blunders.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.3 KB
Line 
1/* $Id: CloudUserProfileListImpl.cpp 73218 2018-07-18 16:19:08Z vboxsync $ */
2/** @file
3 * ICloudUserProfileList 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 "CloudUserProfileListImpl.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 = VWRN_NOT_FOUND;
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 = VERR_INVALID_PARAMETER; /** @todo r=bird: You're mixing error codes... */
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// ICloudUserProfileList implementation
213//
214////////////////////////////////////////////////////////////////////////////////
215CloudUserProfileList::CloudUserProfileList()
216 : mParent(NULL)
217{
218}
219
220CloudUserProfileList::~CloudUserProfileList()
221{
222 LogRel(("CloudUserProfileListImpl::~CloudUserProfileListImpl()\n"));
223 unconst(mParent) = NULL;
224}
225
226HRESULT CloudUserProfileList::FinalConstruct()
227{
228 return BaseFinalConstruct();
229}
230
231void CloudUserProfileList::FinalRelease()
232{
233 uninit();
234
235 BaseFinalRelease();
236}
237
238void CloudUserProfileList::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 CloudUserProfileList::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 CloudUserProfileList::getSupportedPropertiesNames(std::vector<com::Utf8Str> &aPropertiesNames)
262{
263 LogRel(("CloudUserProfileList::getSupportedPropertiesNames:\n"));
264 aPropertiesNames.clear();
265 return VERR_NOT_IMPLEMENTED;
266}
267
268HRESULT CloudUserProfileList::readProfiles(const Utf8Str &strConfigPath)
269{
270 LogRel(("CloudUserProfileList::readProfiles: %s\n", strConfigPath.c_str()));
271 return VERR_NOT_IMPLEMENTED;
272}
273
274HRESULT CloudUserProfileList::getProvider(CloudProviderId_T *aProvider)
275{
276 *aProvider = CloudProviderId_Unknown;
277 LogRel(("CloudUserProfileList::getProvider: %d\n", *aProvider));
278 return VERR_NOT_IMPLEMENTED;
279}
280
281HRESULT CloudUserProfileList::createProfile(const com::Utf8Str &aProfileName,
282 const std::vector<com::Utf8Str> &aNames,
283 const std::vector<com::Utf8Str> &aValues)
284{
285 LogRel(("CloudUserProfileList::createProfile: %s, %d, %d\n", aProfileName.c_str(), aNames.size(), aValues.size()));
286 return VERR_NOT_IMPLEMENTED;
287}
288
289HRESULT CloudUserProfileList::updateProfile(const com::Utf8Str &aProfileName,
290 const std::vector<com::Utf8Str> &aNames,
291 const std::vector<com::Utf8Str> &aValues)
292{
293 LogRel(("CloudUserProfileList::updateProfile: %s, %d, %d\n", aProfileName.c_str(), aNames.size(), aValues.size()));
294 return VERR_NOT_IMPLEMENTED;
295}
296
297HRESULT CloudUserProfileList::getStoredProfilesNames(std::vector<com::Utf8Str> &aProfilesNames)
298{
299
300 LogRel(("CloudUserProfileList::getStoredProfilesNames:\n"));
301 aProfilesNames.clear();
302 return VERR_NOT_IMPLEMENTED;
303}
304
305HRESULT CloudUserProfileList::getProfileProperties(const com::Utf8Str &aProfileName,
306 std::vector<com::Utf8Str> &aReturnNames,
307 std::vector<com::Utf8Str> &aReturnValues)
308{
309 LogRel(("CloudUserProfileList::getProfileProperties: %s\n", aProfileName.c_str()));
310 aReturnNames.clear();
311 aReturnValues.clear();
312 return VERR_NOT_IMPLEMENTED;
313}
314
315HRESULT CloudUserProfileList::getPropertyDescription(const com::Utf8Str &aName,
316 com::Utf8Str &aDescription)
317{
318 LogRel(("CloudUserProfileList::getPropertyDescription: %s, %s\n", aName.c_str(), aDescription.c_str()));
319 return VERR_NOT_IMPLEMENTED;
320}
321
322HRESULT CloudUserProfileList::createCloudClient(const com::Utf8Str &aProfileName,
323 ComPtr<ICloudClient> &aCloudClient)
324{
325 LogRel(("CloudUserProfileList::createCloudClient: %s\n", aProfileName.c_str()));
326
327 if (aCloudClient.isNull())
328 {
329 LogRel(("aCloudClient is NULL\n"));
330 }
331
332 return VERR_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
357OCIUserProfileList::OCIUserProfileList()
358{
359 LogRel(("OCIUserProfileList::OCIUserProfileList()\n"));
360 mpProfiles = new SimpleConfigFile(mParent);
361 LogRel(("Succeeded create SimpleConfigFile\n"));
362}
363
364OCIUserProfileList::~OCIUserProfileList()
365{
366 LogRel(("OCIUserProfileList::~OCIUserProfileList()\n"));
367 if (mpProfiles)
368 delete mpProfiles;
369}
370
371HRESULT OCIUserProfileList::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 OCIUserProfileList::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 throw hrc; /** @todo r=bird: WTF? Try return it! */
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 = VERR_INVALID_PARAMETER; /** @todo r=bird: You're mixing error codes... */
419 }
420
421 return hrc;
422}
423
424HRESULT OCIUserProfileList::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 = VERR_ALREADY_EXISTS;
444
445 return hrc;
446}
447
448HRESULT OCIUserProfileList::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 = VERR_NOT_FOUND; /** @todo r=bird: You're mixing error codes... */
467
468 return hrc;
469}
470
471HRESULT OCIUserProfileList::getStoredProfilesNames(std::vector<com::Utf8Str> &aProfilesNames)
472{
473 HRESULT hrc = S_OK;
474 aProfilesNames = mpProfiles->getSectionsNames();
475 if (aProfilesNames.empty())
476 hrc = VERR_NOT_FOUND; /** @todo r=bird: You're mixing error codes... */
477
478 return hrc;
479}
480
481HRESULT OCIUserProfileList::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 = VERR_NOT_FOUND; /** @todo r=bird: You're mixing error codes... */
506
507 return hrc;
508}
509
510HRESULT OCIUserProfileList::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 OCIUserProfileList::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 OCIUserProfileList::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 OCIUserProfileList::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 = VERR_NOT_FOUND; /** @todo r=bird: You're mixing error codes... */
548
549 return hrc;
550}
551
552HRESULT OCIUserProfileList::i_getProfileProperties(const com::Utf8Str &aProfileName,
553 std::map <Utf8Str, Utf8Str> &aProfile)
554{
555 HRESULT hrc = S_OK;
556 std::map <Utf8Str, Utf8Str> defProfile = mpProfiles->getSectionByName("DEFAULT");
557 std::map <Utf8Str, Utf8Str> reqProfile = mpProfiles->getSectionByName(aProfileName);
558
559 std::map <Utf8Str, Utf8Str>::iterator itDefProfile = defProfile.begin();
560 while (itDefProfile != defProfile.end())
561 {
562 std::map <Utf8Str, Utf8Str>::iterator itProfile = reqProfile.find(itDefProfile->first);
563 if (itProfile == reqProfile.end())
564 {
565 //Add a key=value pair from defProfile into the reqProfile if the key doesn't exist in the reqProfile.
566 reqProfile.insert(*itDefProfile);
567 }
568 ++itDefProfile;
569 }
570
571 if (!reqProfile.empty())
572 aProfile = reqProfile;
573 else
574 hrc = VERR_NOT_FOUND; /** @todo r=bird: You're mixing error codes... */
575
576 return hrc;
577}
578
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