Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements in conddb tools #33859

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion CondCore/CondDB/interface/CredentialStore.h
Expand Up @@ -19,6 +19,13 @@ namespace coral {

} // namespace coral

std::string to_lower(const std::string& s) {
std::string str(s);
for (auto& c : str)
c = tolower(c);
return str;
}

namespace coral_bridge {

class AuthenticationCredentialSet {
Expand Down Expand Up @@ -106,7 +113,7 @@ namespace cond {
const std::string& connectionString,
const std::string& connectionLabel);

bool unsetPermission(const std::string& principal, const std::string& role, const std::string& connectionString);
size_t unsetPermission(const std::string& principal, const std::string& role, const std::string& connectionString);

bool updateConnection(const std::string& connectionLabel, const std::string& userName, const std::string& password);

Expand Down
6 changes: 4 additions & 2 deletions CondCore/CondDB/plugins/RelationalAuthenticationService.cc
Expand Up @@ -44,7 +44,8 @@ void cond::RelationalAuthenticationService::RelationalAuthenticationService::set

const coral::IAuthenticationCredentials&
cond::RelationalAuthenticationService::RelationalAuthenticationService::credentials(
const std::string& connectionString) const {
const std::string& connectionStr) const {
std::string connectionString = to_lower(connectionStr);
const coral::IAuthenticationCredentials* creds = m_cache.get(connectionString);
if (!creds) {
std::string credsStoreConn = m_db.setUpForConnectionString(connectionString, m_authenticationPath);
Expand All @@ -65,8 +66,9 @@ cond::RelationalAuthenticationService::RelationalAuthenticationService::credenti
}

const coral::IAuthenticationCredentials&
cond::RelationalAuthenticationService::RelationalAuthenticationService::credentials(const std::string& connectionString,
cond::RelationalAuthenticationService::RelationalAuthenticationService::credentials(const std::string& connectionStr,
const std::string& role) const {
std::string connectionString = to_lower(connectionStr);
const coral::IAuthenticationCredentials* creds = m_cache.get(connectionString, role);
if (!creds) {
std::string credsStoreConn = m_db.setUpForConnectionString(connectionString, m_authenticationPath);
Expand Down
123 changes: 85 additions & 38 deletions CondCore/CondDB/src/CredentialStore.cc
Expand Up @@ -154,13 +154,6 @@ std::string tname(const std::string& tableName, const std::string& schemaVersion
return prefix + tableName;
}

std::string to_lower(const std::string& s) {
std::string str(s);
for (auto& c : str)
c = tolower(c);
return str;
}

// implementation functions and helpers
namespace cond {

Expand Down Expand Up @@ -304,7 +297,7 @@ namespace cond {
whereData.extend<std::string>(SCHEMA_COL);
whereData[P_ID_COL].data<int>() = principalId;
whereData[ROLE_COL].data<std::string>() = role;
whereData[SCHEMA_COL].data<std::string>() = connectionString;
whereData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
std::stringstream whereClause;
whereClause << P_ID_COL << " = :" << P_ID_COL;
whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
Expand All @@ -326,6 +319,42 @@ namespace cond {
return found;
}

size_t getAuthorizationEntries(const std::string& schemaVersion,
coral::ISchema& schema,
int principalId,
const std::string& role,
const std::string& connectionString) {
std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(AUTHORIZATION_TABLE, schemaVersion)).newQuery());
coral::AttributeList readBuff;
readBuff.extend<int>(AUTH_ID_COL);
coral::AttributeList whereData;
whereData.extend<std::string>(SCHEMA_COL);
std::stringstream whereClause;
whereClause << SCHEMA_COL << " = :" << SCHEMA_COL;
if (principalId >= 0) {
whereData.extend<int>(P_ID_COL);
whereClause << "AND" << P_ID_COL << " = :" << P_ID_COL;
}
if (!role.empty()) {
whereData.extend<std::string>(ROLE_COL);
whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
}
whereData[SCHEMA_COL].data<std::string>() = connectionString;
if (principalId >= 0)
whereData[P_ID_COL].data<int>() = principalId;
if (!role.empty())
whereData[ROLE_COL].data<std::string>() = role;
query->defineOutput(readBuff);
query->addToOutputList(AUTH_ID_COL);
query->setCondition(whereClause.str(), whereData);
coral::ICursor& cursor = query->execute();
size_t n_entries = 0;
while (cursor.next()) {
n_entries += 1;
}
return n_entries;
}

bool getNextSequenceValue(const std::string& schemaVersion,
coral::ISchema& schema,
const std::string& sequenceName,
Expand Down Expand Up @@ -473,7 +502,7 @@ namespace cond {
insertData[AUTH_ID_COL].data<int>() = next;
insertData[P_ID_COL].data<int>() = principalId;
insertData[ROLE_COL].data<std::string>() = role;
insertData[SCHEMA_COL].data<std::string>() = connectionString;
insertData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
insertData[AUTH_KEY_COL].data<std::string>() = encryptedConnectionKey;
insertData[C_ID_COL].data<int>() = connectionId;
editor.insertRow(insertData);
Expand Down Expand Up @@ -1060,40 +1089,56 @@ bool cond::CredentialStore::setPermission(const std::string& principal,
return ret;
}

bool cond::CredentialStore::unsetPermission(const std::string& principal,
const std::string& role,
const std::string& connectionString) {
if (cond::auth::ROLES.find(role) == cond::auth::ROLES.end()) {
size_t cond::CredentialStore::unsetPermission(const std::string& principal,
const std::string& role,
const std::string& connectionString) {
if (!role.empty() && cond::auth::ROLES.find(role) == cond::auth::ROLES.end()) {
throwException(std::string("Role ") + role + " does not exists.", "CredentialStore::unsetPermission");
}
CSScopedSession session(*this);
session.start(false);
coral::ISchema& schema = m_session->nominalSchema();

PrincipalData princData;
bool found = selectPrincipal(m_key.version(), schema, principal, princData);

if (!found) {
std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
throwException(msg, "CredentialStore::unsetPermission");
}
m_log << "Removing permission for principal " << principal << " (id: " << princData.id << ") to access resource "
<< connectionString << " with role " << role << std::endl;
coral::ITableDataEditor& editor = schema.tableHandle(tname(AUTHORIZATION_TABLE, m_key.version())).dataEditor();
coral::AttributeList deleteData;
deleteData.extend<int>(P_ID_COL);
deleteData.extend<std::string>(ROLE_COL);
deleteData.extend<std::string>(SCHEMA_COL);
deleteData[P_ID_COL].data<int>() = princData.id;
deleteData[ROLE_COL].data<std::string>() = role;
deleteData[SCHEMA_COL].data<std::string>() = connectionString;
std::stringstream whereClause;
whereClause << P_ID_COL + " = :" + P_ID_COL;
whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
whereClause << " AND " << SCHEMA_COL << " = :" << SCHEMA_COL;
editor.deleteRows(whereClause.str(), deleteData);
m_log << "Removing permissions to access resource " << connectionString;
if (!role.empty()) {
deleteData.extend<std::string>(ROLE_COL);
m_log << " with role " << role;
}
int princId = -1;
if (!principal.empty()) {
PrincipalData princData;
bool found = selectPrincipal(m_key.version(), schema, principal, princData);

if (!found) {
std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
throwException(msg, "CredentialStore::unsetPermission");
}
deleteData.extend<int>(P_ID_COL);
princId = princData.id;
m_log << " by principal " << principal << " (id: " << princData.id << ")";
}

size_t n_e = getAuthorizationEntries(m_key.version(), schema, princId, role, connectionString);
m_log << ": " << n_e << " authorization entries." << std::endl;
if (n_e) {
deleteData[SCHEMA_COL].data<std::string>() = connectionString;
whereClause << SCHEMA_COL << " = :" << SCHEMA_COL;
if (!role.empty()) {
deleteData[ROLE_COL].data<std::string>() = role;
whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
}
if (!principal.empty()) {
deleteData[P_ID_COL].data<int>() = princId;
whereClause << " AND " << P_ID_COL + " = :" + P_ID_COL;
}
coral::ITableDataEditor& editor = schema.tableHandle(tname(AUTHORIZATION_TABLE, m_key.version())).dataEditor();
editor.deleteRows(whereClause.str(), deleteData);
}
session.close();
return true;
return n_e;
}

bool cond::CredentialStore::updateConnection(const std::string& connectionLabel,
Expand Down Expand Up @@ -1230,8 +1275,10 @@ bool cond::CredentialStore::selectForUser(coral_bridge::AuthenticationCredential
auth::Cipher connCipher(authKey);
std::string verificationString = connCipher.b64decrypt(row["CREDS." + VERIFICATION_KEY_COL].data<std::string>());
if (verificationString == connectionLabel) {
destinationData.registerCredentials(
connectionString, role, connCipher.b64decrypt(encryptedUserName), connCipher.b64decrypt(encryptedPassword));
destinationData.registerCredentials(to_lower(connectionString),
role,
connCipher.b64decrypt(encryptedUserName),
connCipher.b64decrypt(encryptedPassword));
}
}
session.close();
Expand Down Expand Up @@ -1260,7 +1307,7 @@ std::pair<std::string, std::string> cond::CredentialStore::getUserCredentials(co
whereData.extend<std::string>(SCHEMA_COL);
whereData.extend<std::string>(ROLE_COL);
whereData[P_ID_COL].data<int>() = m_principalId;
whereData[SCHEMA_COL].data<std::string>() = connectionString;
whereData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
whereData[ROLE_COL].data<std::string>() = role;
std::stringstream whereClause;
whereClause << "AUTHO." << C_ID_COL << "="
Expand Down Expand Up @@ -1446,7 +1493,7 @@ bool cond::CredentialStore::selectPermissions(const std::string& principalName,
}
if (!connectionString.empty()) {
whereData.extend<std::string>(SCHEMA_COL);
whereData[SCHEMA_COL].data<std::string>() = connectionString;
whereData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
whereClause << " AND AUTHO." << SCHEMA_COL << " = :" << SCHEMA_COL;
}

Expand Down Expand Up @@ -1525,7 +1572,7 @@ bool cond::CredentialStore::exportAll(coral_bridge::AuthenticationCredentialSet&
userName = cipher1.b64decrypt(encryptedUserName);
password = cipher1.b64decrypt(encryptedPassword);
}
data.registerCredentials(connectionString, role, userName, password);
data.registerCredentials(to_lower(connectionString), role, userName, password);
found = true;
}
session.close();
Expand Down
27 changes: 22 additions & 5 deletions CondCore/Utilities/bin/cmscond_authentication_manager.cpp
Expand Up @@ -202,12 +202,29 @@ int cond::AuthenticationManager::execute() {
}

if (unset_perm && not_exec) {
std::string principal = getOptionValue<std::string>("princ_name");
std::string role = getOptionValue<std::string>("role");
std::string connectionString = getOptionValue<std::string>("connectionString");
credDb.unsetPermission(principal, role, connectionString);
std::cout << "Permission for principal " << principal << " to access resource " << connectionString << " with role "
<< role << " has been unset." << std::endl;
std::string principal("");
if (hasOptionValue("princ_name"))
principal = getOptionValue<std::string>("princ_name");
std::string role("");
if (hasOptionValue("role"))
role = getOptionValue<std::string>("role");
size_t n = credDb.unsetPermission(principal, role, connectionString);
if (n) {
std::cout << n << " permissions to access resource " << connectionString;
if (!role.empty())
std::cout << " with role " << role;
std::cout << " have been unset";
if (!principal.empty())
std::cout << " for principal " << principal << " ";
} else {
std::cout << "No Permission found to access resource " << connectionString;
if (!role.empty())
std::cout << " with role " << role;
if (!principal.empty())
std::cout << " for principal " << principal << " ";
}
std::cout << "." << std::endl;
not_exec = false;
}

Expand Down
2 changes: 1 addition & 1 deletion CondCore/Utilities/python/conddblib.py
Expand Up @@ -18,7 +18,7 @@
import enum
from sqlalchemy import Enum

schema_name = 'CMS_CONDITIONS'
schema_name = 'cms_conditions'
dbuser_name = 'cms_conditions'
dbreader_user_name = 'cms_cond_general_r'
dbwriter_user_name = 'cms_cond_general_w'
Expand Down
69 changes: 69 additions & 0 deletions CondCore/Utilities/scripts/conddb
Expand Up @@ -20,6 +20,7 @@ import socket

import calendar
import sqlalchemy
import json

from prettytable import PrettyTable

Expand Down Expand Up @@ -2630,6 +2631,67 @@ def setProtection( args ):
logging.info(note)
logging.info('Tag header updated. Action(s): %s' %action)
return 0

def query_object(args):
connection = connect(args)
session = connection.session()
if not args.tag and not args.global_tag and not args.payload:
logging.error('The object type for the query has not been specified.')
return -1
if (args.tag and args.global_tag) or (args.tag and args.payload) or (args.global_tag and args.payload):
logging.error('Only one object type for the query can be specified.')
return -1
found = 1
if args.tag:
Tag = session.get_dbtype(conddb.Tag)
query = session.query(Tag.description,Tag.time_type,Tag.object_type,Tag.synchronization,Tag.insertion_time,Tag.modification_time).filter(Tag.name == args.unique_key).all()
table = []
for res in query:
found = 0
table.append((args.unique_key,res[0],res[1],res[2],res[3],res[4],res[5]))
if found==0:
output_table(args,table,['Tag name','Description','Time Type','Object Type','Synchronization','Insertion Time','Modification Time'])
else:
logging.info('Tag %s has not been found.'%args.unique_key)
if args.global_tag:
GlobalTag = session.get_dbtype(conddb.GlobalTag)
query = session.query(GlobalTag.description,GlobalTag.release,GlobalTag.insertion_time,GlobalTag.snapshot_time).filter(GlobalTag.name == args.unique_key).all()
table = []
for res in query:
found = 0
table.append((args.unique_key,res[0],res[1],res[2],res[3]))
if found==0:
output_table(args,table,['Global Tag name','Description','Release','Insertion Time','Snapshot Time'])
else:
logging.info('Global Tag %s has not been found.'%args.unique_key)
if args.payload:
Payload = session.get_dbtype(conddb.Payload)
query = session.query(Payload.object_type,Payload.streamer_info,Payload.insertion_time).filter(Payload.hash == args.unique_key).all()
table = []
header = None
for res in query:
found = 0
streamer_info = str(res[1])
row = (args.unique_key,res[0],)
header = ['Payload hash','Object type']
if streamer_info != '0':
payload_md = json.loads(streamer_info)
for k in sorted(payload_md.keys()):
header.append(k)
row += (payload_md[k],)
else:
row += (' ',)
header.append('Streamer Info')
row += (res[2],)
table.append(row)
header.append('Insertion Time')
if found==0:
output_table(args,table,header)
else:
logging.info('Payload %s has not been found.'%args.unique_key)

return found


def main():
'''Entry point.
Expand Down Expand Up @@ -2790,6 +2852,13 @@ def main():
parser_setProtection.add_argument('--remove','-r',action='store_true', help='Remove the specified protection')
parser_setProtection.set_defaults(func=setProtection)

parser_query = parser_subparsers.add_parser('query', description='Query the database to get information about condition metadata')
parser_query.add_argument('unique_key', help="The unique key for the query")
parser_query.add_argument('--tag','-t',action='store_true', help="Query a tag object")
parser_query.add_argument('--global_tag','-gt',action='store_true', help="Query a global tag object")
parser_query.add_argument('--payload','-p',action='store_true', help="Query a payload object")
parser_query.set_defaults(func=query_object)

args = parser.parse_args()
logging.basicConfig(
format = '[%(asctime)s] %(levelname)s: %(message)s',
Expand Down