#include "PgServerObject.h" #include "ArrayParser.h" #include namespace { QString privilegeLetterToKeyword(char c) { switch (c) { case 'r': return "SELECT"; case 'w': return "UPDATE"; case 'a': return "INSERT"; case 'd': return "DELETE"; case 'D': return "TRUNCATE"; case 'x': return "REFERENCES"; case 't': return "TRIGGER"; case 'X': return "EXECUTE"; case 'U': return "USAGE"; case 'C': return "CREATE"; case 'c': return "CONNECT"; case 'T': return "TEMPORARY"; } throw std::runtime_error("Unexpected value for c in privilegeLetterToKeyword"); } } char privilegeToChar(Privilege p) { switch (p) { case Privilege::Select: return 'r'; case Privilege::Update: return 'w'; case Privilege::Insert: return 'a'; case Privilege::Delete: return 'd'; case Privilege::Truncate: return 'D'; case Privilege::References: return 'x'; case Privilege::Trigger: return 't'; case Privilege::Execute: return 'X'; case Privilege::Usage: return 'U'; case Privilege::Create: return 'C'; case Privilege::Connect: return 'c'; case Privilege::Temporary: return 'T'; } throw std::runtime_error("Unexpected value for privilege in privilegeToChar"); } PgAcl::PgAcl(const QString &acl) { setFromString(acl); } void PgAcl::setFromString(const QString &acl) { m_grantee = acl.section('=', 0, 0); auto t = acl.section('=', 1); m_privileges = t.section('/', 0, 0); m_grantor = t.section('/', 1); } PrivValue PgAcl::privilege(Privilege priv) const { char c = privilegeToChar(priv); return privilege(c); } PrivValue PgAcl::privilege(char c) const { int pos = m_privileges.indexOf(c); if (pos >= 0) { if ( (pos+1) < m_privileges.length() && m_privileges[pos+1] == '*') return PrivValue::YesWithGrant; return PrivValue::Yes; } return PrivValue::No; } QString PgAcl::singleString() const { return m_grantee % "=" % m_privileges % "/" % m_grantor; } //void operator<<(AclList &s, const Pgsql::Value &v) void operator<<(PgAcl &acl, const Pgsql::Value &v) { acl.setFromString(v); // const char *c = v.c_str(); // Pgsql::ArrayParser parser(c); // while (true) { // auto elem = parser.GetNextElem(); // if (!elem.ok) // break; // auto&& v = elem.value.value_or(""); // s.emplace_back(QString(v.data())); // } } namespace Pgsql { template <> PgAcl StringToArrayElem(std::string_view sv) { return PgAcl(QString::fromUtf8(sv.data(), static_cast(sv.length()))); } } void PgServerObject::setAcls(AclList acls) { m_acls = std::move(acls); } QString PgServerObject::aclString() const { QString result; for (auto&& acl : m_acls) { if (result.isEmpty()) result += "{"; else result += ","; result += acl.singleString(); } if (!result.isEmpty()) result += "}"; return result; } QString PgServerObject::grantSql(const QString &all_pattern, const QString &grantee, const QString &column) const { QString grant; // wxString grant, str, user, grantFor, tmpUser; // if (_grantFor.IsNull()) // { // grantFor = GetTypeName(); // grantFor.MakeUpper(); // grantFor += wxT(" ") + GetQuotedFullIdentifier(); // } // else // grantFor = _grantFor; // if (!acl.IsNull()) // { // if (acl == wxT("{}")) // { // grant += GetPrivileges(allPattern, str, grantFor, wxT("public"), qtIdent(_column)); // grant += GetPrivileges(allPattern, str, grantFor, qtIdent(owner), qtIdent(_column)); // } // else // { // // checks if certain privilege is granted to public // bool grantedToPublic = false; // // checks if certain privilege is granted to owner // bool grantedToOwner = false; // queryTokenizer acls(acl.Mid(1, acl.Length() - 2), ','); // while (acls.HasMoreTokens()) // { // str = acls.GetNextToken(); // if (str.Left(1) == '"') // str = str.Mid(1, str.Length() - 2); // user = str.BeforeFirst('='); // str = str.AfterFirst('=').BeforeFirst('/'); // if (user == wxT("")) // { // user = wxT("public"); // grantedToPublic = true; // } // else // { // if (user.Left(6) == wxT("group ")) // { // tmpUser = user.Mid(6); // if (user.Mid(6).StartsWith(wxT("\\\"")) && user.Mid(6).EndsWith(wxT("\\\""))) // user = wxT("GROUP ") + qtIdent(user.Mid(8, user.Length() - 10)); // else // user = wxT("GROUP ") + qtIdent(user.Mid(6)); // } // else // { // tmpUser = user; // if (user.StartsWith(wxT("\\\"")) && user.EndsWith(wxT("\\\""))) // user = qtIdent(user.Mid(2, user.Length() - 4)); // else // user = qtIdent(user); // } // if (tmpUser.Contains(owner)) // grantedToOwner = true; // } // grant += GetPrivileges(allPattern, str, grantFor, user, qtIdent(_column)); // } // str = wxEmptyString; // int metaType = GetMetaType(); // // We check here that whether the user has revoked prvileges granted to databases, functions // // and languages. If so then this must be part of reverse engineered sql statement // if (!grantedToPublic && (metaType == PGM_LANGUAGE || metaType == PGM_FUNCTION || metaType == PGM_DATABASE)) // grant += GetPrivileges(allPattern, str, grantFor, wxT("public"), qtIdent(_column)); // // We check here that whether the owner has revoked prvileges on himself to this postgres // // object. If so then this must be part of reverse engineered sql statement // if (!grantedToOwner) // grant += GetPrivileges(allPattern, str, grantFor, qtIdent(owner), qtIdent(_column)); // } // } return grant; }