6 #include "CoralBase/AttributeList.h"
7 #include "CoralBase/Attribute.h"
8 #include "CoralKernel/Context.h"
9 #include "CoralCommon/URIParser.h"
10 #include "RelationalAccess/AuthenticationCredentials.h"
11 #include "RelationalAccess/IBulkOperation.h"
12 #include "RelationalAccess/IConnection.h"
13 #include "RelationalAccess/ISession.h"
14 #include "RelationalAccess/IRelationalService.h"
15 #include "RelationalAccess/IRelationalDomain.h"
16 #include "RelationalAccess/ITransaction.h"
17 #include "RelationalAccess/ISchema.h"
18 #include "RelationalAccess/ITable.h"
19 #include "RelationalAccess/TableDescription.h"
20 #include "RelationalAccess/ITableDataEditor.h"
21 #include "RelationalAccess/ITablePrivilegeManager.h"
22 #include "RelationalAccess/IQuery.h"
23 #include "RelationalAccess/ICursor.h"
25 #include "RelationalAccess/AuthenticationCredentials.h"
29 #include <boost/filesystem.hpp>
38 for (
std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
40 iData != m_data.end();
57 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
59 if (iData == m_data.end()) {
60 iData = m_data.insert(std::make_pair(connKey,
new coral::AuthenticationCredentials(
serviceName))).first;
62 iData = m_data.insert(std::make_pair(connKey,
new coral::AuthenticationCredentials(
serviceName))).first;
63 iData->second->registerItem(itemName, itemValue);
77 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
79 if (iData != m_data.end()) {
81 m_data.erase(connKey);
83 iData = m_data.insert(std::make_pair(connKey,
new coral::AuthenticationCredentials(
serviceName))).first;
84 iData->second->registerItem(coral::IAuthenticationCredentials::userItem(),
userName);
85 iData->second->registerItem(coral::IAuthenticationCredentials::passwordItem(),
password);
89 for (
std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iData =
91 iData !=
data.m_data.end();
93 registerCredentials(iData->first.first,
95 iData->second->valueForItem(coral::IAuthenticationCredentials::userItem()),
96 iData->second->valueForItem(coral::IAuthenticationCredentials::passwordItem()));
107 const coral::IAuthenticationCredentials*
ret =
nullptr;
109 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iData =
110 m_data.find(connKey);
111 if (iData != m_data.end()) {
117 const std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>&
177 void start(
bool readOnly =
true) { m_store.startSession(readOnly); }
178 void close() { m_store.closeSession(); }
193 coral::AttributeList readBuff;
198 coral::AttributeList whereData;
202 query->defineOutput(readBuff);
207 query->setCondition(whereClause, whereData);
208 coral::ICursor& cursor =
query->execute();
212 const coral::AttributeList& row = cursor.currentRow();
232 coral::AttributeList readBuff;
238 coral::AttributeList whereData;
242 query->defineOutput(readBuff);
248 query->setCondition(whereClause, whereData);
249 coral::ICursor& cursor =
query->execute();
252 const coral::AttributeList& row = cursor.currentRow();
276 coral::AttributeList readBuff;
280 coral::AttributeList whereData;
284 whereData[
P_ID_COL].data<
int>() = principalId;
287 std::stringstream whereClause;
291 query->defineOutput(readBuff);
295 query->setCondition(whereClause.str(), whereData);
296 coral::ICursor& cursor =
query->execute();
299 const coral::AttributeList& row = cursor.currentRow();
311 query->limitReturnedRows(1, 0);
314 query->setForUpdate();
316 coral::AttributeList rowData;
319 query->setCondition(whereClause, rowData);
320 coral::ICursor& cursor =
query->execute();
322 value = cursor.currentRow().begin()->data<
int>() + 1;
328 coral::AttributeList updateData;
333 coral::AttributeList::iterator iAttribute = updateData.begin();
336 iAttribute->data<
int>() =
value;
337 schema.tableHandle(
SEQUENCE_TABLE_NAME).dataEditor().updateRows(setClause, whClause, updateData);
354 int principalId = princData.
id;
359 coral::AttributeList updateData;
368 std::stringstream setClause;
373 editor.updateRows(setClause.str(), whereClause, updateData);
376 principalKey = adminKey;
386 coral::AttributeList authData;
387 editor0.rowBuffer(authData);
393 editor0.insertRow(authData);
396 return std::make_pair(principalId, principalKey);
413 coral::AttributeList updateData;
418 updateData[
C_ID_COL].data<
int>() = connectionId;
422 editor.updateRows(setCl, whereCl, updateData);
428 coral::AttributeList insertData;
436 insertData[
P_ID_COL].data<
int>() = principalId;
440 insertData[
C_ID_COL].data<
int>() = connectionId;
441 editor.insertRow(insertData);
454 int connId = credsData.
id;
463 if (verificationKey != connectionLabel) {
464 throwException(
"Decoding of connection key failed.",
"CredentialStore::updateConnection");
470 coral::AttributeList updateData;
477 std::stringstream setCl;
481 editor.updateRows(setCl.str(), whereCl, updateData);
496 coral::AttributeList insertData;
510 editor.insertRow(insertData);
512 return std::make_pair(connId, connectionKey);
519 if (m_session.get()) {
520 if (m_session->transaction().isActive()) {
522 m_session->transaction().commit();
524 m_session->transaction().rollback();
527 m_session->endUserSession();
530 if (m_connection.get()) {
531 m_connection->disconnect();
533 m_connection.reset();
537 coral::IHandle<coral::IRelationalService> relationalService =
539 if (!relationalService.isValid()) {
543 coral::IRelationalDomain& domain = relationalService->domainForConnection(
connectionString);
544 std::pair<std::string, std::string> connTokens = domain.decodeUserConnectionString(
connectionString);
545 m_connection.reset(domain.newConnection(connTokens.first));
546 m_connection->connect();
554 coral::AccessMode accessMode = coral::ReadOnly;
556 accessMode = coral::Update;
557 m_session.reset(m_connection->newSession(schemaName, accessMode));
560 m_session->transaction().start(readMode);
566 std::pair<std::string, std::string> connTokens = openConnection(
connectionString);
572 if (!m_serviceData) {
573 throwException(
"The credential store has not been initialized.",
"cond::CredentialStore::openConnection");
575 const std::string& storeConnectionString = m_serviceData->connectionString;
577 std::pair<std::string, std::string> connTokens = openConnection(storeConnectionString);
584 coral::ISchema& schema = m_session->nominalSchema();
587 throwException(
"Credential database does not exists in \"" + storeConnectionString +
"\"",
588 "CredentialStore::startSession");
591 const std::string& principalName = m_key.principalName();
594 if (!
selectPrincipal(m_session->nominalSchema(), principalName, princData)) {
595 throwException(
"Invalid credentials provided.(0)",
"CredentialStore::startSession");
599 if (verifStr != principalName) {
600 throwException(
"Invalid credentials provided (1)",
"CredentialStore::startSession");
603 m_principalId = princData.
id;
604 m_principalKey = cipher0.b64decrypt(princData.
principalKey);
609 if (adminKey != m_principalKey) {
611 throwException(
"Provided credentials does not allow admin operation.",
"CredentialStore::openSession");
615 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
618 coral::AttributeList readBuff;
624 coral::AttributeList whereData;
628 whereData[
P_ID_COL].data<
int>() = m_principalId;
631 std::stringstream whereClause;
636 query->defineOutput(readBuff);
642 query->setCondition(whereClause.str(), whereData);
643 coral::ICursor& cursor =
query->execute();
648 const coral::AttributeList& row = cursor.currentRow();
656 if (cipher1.
b64decrypt(verificationKey) != connLabel) {
657 throwException(
"Could not decrypt credentials.Provided key is invalid.",
"CredentialStore::startSession");
659 writeUserName = cipher1.
b64decrypt(encryptedUserName);
660 writePassword = cipher1.
b64decrypt(encryptedPassword);
664 throwException(
"Provided credentials are invalid for write access.",
"CredentialStore::openSession");
666 m_session->transaction().commit();
667 m_session->endUserSession();
668 openSession(connTokens.second, writeUserName, writePassword,
false);
679 m_serviceData(nullptr),
686 throwException(
"Service name has not been provided.",
"cond::CredentialStore::setUpConnection");
688 m_serviceName.clear();
689 m_serviceData =
nullptr;
692 throwException(
"The authentication Path has not been provided.",
"cond::CredentialStore::setUpForService");
695 if (!boost::filesystem::exists(
authPath) || !boost::filesystem::is_directory(
authPath)) {
696 throwException(
"Authentication Path is invalid.",
"cond::CredentialStore::setUpForService");
703 std::map<std::string, auth::ServiceCredentials>::const_iterator iK = m_key.services().find(
serviceName);
704 if (iK == m_key.services().end()) {
706 msg +=
"Service \"" +
serviceName +
"\" can't be open with the current key.";
710 m_serviceData = &iK->second;
711 return m_serviceData->connectionString;
716 coral::IHandle<coral::IRelationalService> relationalService =
718 if (!relationalService.isValid()) {
722 coral::IRelationalDomain& domain = relationalService->domainForConnection(
connectionString);
723 std::pair<std::string, std::string> connTokens = domain.decodeUserConnectionString(
connectionString);
730 coral::AttributeList insertData;
733 coral::AttributeList::iterator iAttribute = insertData.begin();
736 iAttribute->data<
int>() = -1;
746 coral::ISchema& schema = m_session->nominalSchema();
748 throwException(
"Credential database, already exists.",
"CredentialStore::create");
751 coral::TableDescription dseq;
754 dseq.insertColumn(
SEQUENCE_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>());
756 dseq.insertColumn(
SEQUENCE_VALUE_COL, coral::AttributeSpecification::typeNameForType<int>());
759 schema.createTable(dseq);
761 int columnSize = 2000;
766 coral::TableDescription descr0;
768 descr0.insertColumn(
PRINCIPAL_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
770 PRINCIPAL_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
772 VERIFICATION_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
774 PRINCIPAL_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
775 descr0.insertColumn(
ADMIN_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
781 std::vector<std::string> columnsUnique;
783 descr0.setUniqueConstraint(columnsUnique);
784 std::vector<std::string> columnsForIndex;
786 descr0.setPrimaryKey(columnsForIndex);
787 schema.createTable(descr0);
791 coral::TableDescription descr1;
793 descr1.insertColumn(
AUTH_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
794 descr1.insertColumn(
P_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
795 descr1.insertColumn(
ROLE_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
796 descr1.insertColumn(
SCHEMA_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
797 descr1.insertColumn(
AUTH_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
798 descr1.insertColumn(
C_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
800 descr1.setNotNullConstraint(
P_ID_COL);
801 descr1.setNotNullConstraint(
ROLE_COL);
804 descr1.setNotNullConstraint(
C_ID_COL);
805 columnsUnique.clear();
809 descr1.setUniqueConstraint(columnsUnique);
810 columnsForIndex.clear();
812 descr1.setPrimaryKey(columnsForIndex);
813 schema.createTable(descr1);
817 coral::TableDescription descr2;
819 descr2.insertColumn(
CONNECTION_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
821 CONNECTION_LABEL_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
822 descr2.insertColumn(
USERNAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
823 descr2.insertColumn(
PASSWORD_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
825 VERIFICATION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
827 CONNECTION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize,
false);
834 columnsUnique.clear();
836 descr2.setUniqueConstraint(columnsUnique);
837 columnsForIndex.clear();
839 descr2.setPrimaryKey(columnsForIndex);
840 schema.createTable(descr2);
845 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
848 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
851 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
853 std::cout <<
"WARNING: Could not grant select access to user " << m_serviceData->userName <<
": [" <<
e.what()
858 auto princData =
updatePrincipalData(schema, m_key.principalKey(), m_key.principalName(), m_principalKey,
true);
878 coral::ISchema& schema = m_session->nominalSchema();
888 if (!m_serviceData) {
889 throwException(
"The credential store has not been initialized.",
"cond::CredentialStore::installAdmin");
896 coral::ISchema& schema = m_session->nominalSchema();
897 const std::string& principalName = m_key.principalName();
898 const std::string& authenticationKey = m_key.principalKey();
902 msg += principalName +
"\" has not been found.";
1006 session.
start(
false);
1007 coral::ISchema& schema = m_session->nominalSchema();
1008 auto princData =
updatePrincipalData(schema, m_principalKey, principalName, authenticationKey);
1011 int princId = princData.first;
1013 std::string connString = m_serviceData->connectionString;
1016 throwException(
"The current operating user is not admin user on the underlying Credential Store.",
1017 "CredentialStore::updatePrincipal");
1022 throwException(
"Credential Store connection has not been defined.",
"CredentialStore::updatePrincipal");
1042 session.
start(
false);
1044 coral::ISchema& schema = m_session->nominalSchema();
1050 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1058 std::string msg =
"Connection named \"" + connectionLabel +
"\" does not exist in the database.";
1078 session.
start(
false);
1079 coral::ISchema& schema = m_session->nominalSchema();
1085 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1090 coral::AttributeList deleteData;
1094 deleteData[
P_ID_COL].data<
int>() = princData.
id;
1097 std::stringstream whereClause;
1101 editor.deleteRows(whereClause.str(), deleteData);
1110 session.
start(
false);
1112 m_session->transaction().start();
1113 coral::ISchema& schema = m_session->nominalSchema();
1122 session.
start(
false);
1123 coral::ISchema& schema = m_session->nominalSchema();
1129 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1135 coral::AttributeList deleteData0;
1137 deleteData0[
P_ID_COL].data<
int>() = princData.
id;
1139 editor0.deleteRows(whereClause0, deleteData0);
1143 coral::AttributeList deleteData1;
1147 editor1.deleteRows(whereClause1, deleteData1);
1156 session.
start(
false);
1157 coral::ISchema& schema = m_session->nominalSchema();
1163 std::string msg =
"Connection named \"" + connectionLabel +
"\" does not exist in the database.";
1169 coral::AttributeList deleteData0;
1171 deleteData0[
C_ID_COL].data<
int>() = credsData.
id;
1173 editor0.deleteRows(whereClause0, deleteData0);
1177 coral::AttributeList deleteData1;
1181 editor1.deleteRows(whereClause1, deleteData1);
1190 session.
start(
true);
1191 coral::ISchema& schema = m_session->nominalSchema();
1195 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1198 coral::AttributeList readBuff;
1206 coral::AttributeList whereData;
1208 whereData[
P_ID_COL].data<
int>() = m_principalId;
1209 std::stringstream whereClause;
1210 whereClause <<
"AUTHO." <<
C_ID_COL <<
"="
1212 whereClause <<
" AND "
1214 query->defineOutput(readBuff);
1222 query->setCondition(whereClause.str(), whereData);
1223 coral::ICursor& cursor =
query->execute();
1224 while (cursor.next()) {
1225 const coral::AttributeList& row = cursor.currentRow();
1235 if (connCipher.
b64decrypt(encryptedLabel) == connectionLabel) {
1246 bool forceUpdateConnection) {
1248 session.
start(
false);
1249 coral::ISchema& schema = m_session->nominalSchema();
1255 std::string msg =
"Principal \"" + principal +
"\" does not exist in the database.";
1259 bool imported =
false;
1263 const std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>& creds =
dataSource.data();
1264 for (
std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iConn =
1266 iConn != creds.end();
1273 std::string userName = iConn->second->valueForItem(coral::IAuthenticationCredentials::userItem());
1274 std::string password = iConn->second->valueForItem(coral::IAuthenticationCredentials::passwordItem());
1289 session.
start(
true);
1290 coral::ISchema& schema = m_session->nominalSchema();
1293 coral::AttributeList readBuff;
1295 query->defineOutput(readBuff);
1297 coral::ICursor& cursor =
query->execute();
1299 while (cursor.next()) {
1301 const coral::AttributeList& row = cursor.currentRow();
1310 session.
start(
true);
1311 coral::ISchema& schema = m_session->nominalSchema();
1314 coral::AttributeList readBuff;
1320 query->defineOutput(readBuff);
1326 coral::ICursor& cursor =
query->execute();
1329 while (cursor.next()) {
1332 const coral::AttributeList& row = cursor.currentRow();
1339 if (verif == connLabel) {
1357 session.
start(
true);
1358 coral::ISchema& schema = m_session->nominalSchema();
1359 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1363 coral::AttributeList readBuff;
1368 coral::AttributeList whereData;
1369 std::stringstream whereClause;
1371 whereClause <<
" AND AUTHO." <<
C_ID_COL <<
"="
1373 if (!principalName.empty()) {
1378 if (!role.empty()) {
1389 query->defineOutput(readBuff);
1394 query->setCondition(whereClause.str(), whereData);
1398 coral::ICursor& cursor =
query->execute();
1400 while (cursor.next()) {
1401 const coral::AttributeList& row = cursor.currentRow();
1416 session.
start(
true);
1417 coral::ISchema& schema = m_session->nominalSchema();
1418 std::unique_ptr<coral::IQuery>
query(schema.newQuery());
1421 coral::AttributeList readBuff;
1429 coral::AttributeList whereData;
1430 std::stringstream whereClause;
1431 whereClause <<
"AUTHO." <<
C_ID_COL <<
"="
1434 query->defineOutput(readBuff);
1442 query->setCondition(whereClause.str(), whereData);
1443 coral::ICursor& cursor =
query->execute();
1446 while (cursor.next()) {
1447 const coral::AttributeList& row = cursor.currentRow();
1458 if (verifKey == connectionLabel) {