PgServerObject now contains a list of acl's for the object so all the different objects

can use this implementation.
This commit is contained in:
eelke 2018-12-24 07:51:27 +01:00
parent efb3e71556
commit 93c8b49f61
6 changed files with 284 additions and 36 deletions

View file

@ -1,2 +1,211 @@
#include "PgServerObject.h"
#include "ArrayParser.h"
#include <QStringBuilder>
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<PgAcl>(std::string_view sv)
{
return PgAcl(QString::fromUtf8(sv.data(), static_cast<int>(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;
}