mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
936 lines
23 KiB
C++
936 lines
23 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// dlgRole.cpp - PostgreSQL Role Property
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pgAdmin3.h"
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
|
|
// App headers
|
|
#include "utils/misc.h"
|
|
#include "dlg/dlgRole.h"
|
|
#include "schema/pgRole.h"
|
|
#include "ctl/ctlSeclabelPanel.h"
|
|
|
|
|
|
// pointer to controls
|
|
#define txtPasswd CTRL_TEXT("txtPasswd")
|
|
#define txtRePasswd CTRL_TEXT("txtRePasswd")
|
|
#define datValidUntil CTRL_CALENDAR("datValidUntil")
|
|
#define timValidUntil CTRL_TIME("timValidUntil")
|
|
#define chkCanLogin CTRL_CHECKBOX("chkCanLogin")
|
|
#define chkSuperuser CTRL_CHECKBOX("chkSuperuser")
|
|
#define chkInherits CTRL_CHECKBOX("chkInherits")
|
|
#define chkCreateDB CTRL_CHECKBOX("chkCreateDB")
|
|
#define chkCreateRole CTRL_CHECKBOX("chkCreateRole")
|
|
#define chkUpdateCat CTRL_CHECKBOX("chkUpdateCat")
|
|
#define chkReplication CTRL_CHECKBOX("chkReplication")
|
|
#define txtConnectionLimit CTRL_TEXT("txtConnectionLimit")
|
|
|
|
#define lbRolesNotIn CTRL_LISTBOX("lbRolesNotIn")
|
|
#define lbRolesIn CTRL_LISTBOX("lbRolesIn")
|
|
#define btnAddRole CTRL_BUTTON("btnAddRole")
|
|
#define btnDelRole CTRL_BUTTON("btnDelRole")
|
|
#define chkAdminOption CTRL_CHECKBOX("chkAdminOption")
|
|
|
|
#define lstVariables CTRL_LISTVIEW("lstVariables")
|
|
#define btnAdd CTRL_BUTTON("wxID_ADD")
|
|
#define btnRemove CTRL_BUTTON("wxID_REMOVE")
|
|
#define cbVarname CTRL_COMBOBOX2("cbVarname")
|
|
#define cbVarDbname CTRL_COMBOBOX2("cbVarDbname")
|
|
#define txtValue CTRL_TEXT("txtValue")
|
|
#define chkValue CTRL_CHECKBOX("chkValue")
|
|
|
|
|
|
|
|
dlgProperty *pgLoginRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
|
{
|
|
return new dlgRole(this, frame, (pgRole *)node, true);
|
|
}
|
|
|
|
dlgProperty *pgGroupRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
|
{
|
|
return new dlgRole(this, frame, (pgRole *)node, false);
|
|
}
|
|
|
|
BEGIN_EVENT_TABLE(dlgRole, dlgProperty)
|
|
EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeCal)
|
|
EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeDate)
|
|
EVT_SPIN(XRCID("timValidUntil"), dlgRole::OnChangeSpin)
|
|
EVT_TEXT(XRCID("timValidUntil"), dlgRole::OnChange)
|
|
|
|
EVT_LISTBOX_DCLICK(XRCID("lbRolesNotIn"), dlgRole::OnRoleAdd)
|
|
EVT_LISTBOX_DCLICK(XRCID("lbRolesIn"), dlgRole::OnRoleRemove)
|
|
EVT_TEXT(XRCID("txtPasswd"), dlgRole::OnChangePasswd)
|
|
EVT_TEXT(XRCID("txtRePasswd"), dlgRole::OnChangePasswd)
|
|
EVT_CHECKBOX(XRCID("chkCanLogin"), dlgRole::OnChange)
|
|
EVT_CHECKBOX(XRCID("chkInherits"), dlgRole::OnChange)
|
|
EVT_CHECKBOX(XRCID("chkCreateDB"), dlgRole::OnChange)
|
|
EVT_CHECKBOX(XRCID("chkUpdateCat"), dlgRole::OnChange)
|
|
EVT_CHECKBOX(XRCID("chkSuperuser"), dlgRole::OnChangeSuperuser)
|
|
EVT_CHECKBOX(XRCID("chkCreateRole"), dlgRole::OnChange)
|
|
EVT_CHECKBOX(XRCID("chkReplication"), dlgRole::OnChange)
|
|
EVT_TEXT(XRCID("txtConnectionLimit"), dlgRole::OnChange)
|
|
|
|
EVT_BUTTON(XRCID("btnAddRole"), dlgRole::OnRoleAdd)
|
|
EVT_BUTTON(XRCID("btnDelRole"), dlgRole::OnRoleRemove)
|
|
|
|
EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgRole::OnVarSelChange)
|
|
EVT_BUTTON(wxID_ADD, dlgRole::OnVarAdd)
|
|
EVT_BUTTON(wxID_REMOVE, dlgRole::OnVarRemove)
|
|
EVT_TEXT(XRCID("cbVarname"), dlgRole::OnVarnameSelChange)
|
|
EVT_TEXT(XRCID("cbVarDbname"), dlgRole::OnVarnameSelChange)
|
|
EVT_COMBOBOX(XRCID("cbVarname"), dlgRole::OnVarnameSelChange)
|
|
|
|
EVT_BUTTON(wxID_OK, dlgRole::OnOK)
|
|
|
|
#ifdef __WXMAC__
|
|
EVT_SIZE( dlgRole::OnChangeSize)
|
|
#endif
|
|
END_EVENT_TABLE();
|
|
|
|
|
|
|
|
dlgRole::dlgRole(pgaFactory *f, frmMain *frame, pgRole *node, bool chkLogin)
|
|
: dlgProperty(f, frame, wxT("dlgRole"))
|
|
{
|
|
role = node;
|
|
lstVariables->CreateColumns(0, _("Database"), _("Variable"), _("Value"), -1);
|
|
btnOK->Disable();
|
|
chkValue->Hide();
|
|
if (chkLogin)
|
|
chkCanLogin->SetValue(true);
|
|
|
|
seclabelPage = new ctlSeclabelPanel(nbNotebook);
|
|
}
|
|
|
|
|
|
pgObject *dlgRole::GetObject()
|
|
{
|
|
return role;
|
|
}
|
|
|
|
|
|
#ifdef __WXMAC__
|
|
void dlgRole::OnChangeSize(wxSizeEvent &ev)
|
|
{
|
|
lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord,
|
|
ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
|
|
if (GetAutoLayout())
|
|
{
|
|
Layout();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
int dlgRole::Go(bool modal)
|
|
{
|
|
|
|
// In wxMac, the text deletion of "calenderBox" is not raising the EVT_CALENDAR_SEL_CHANGED, EVT_DATE_CHANGED events properly.
|
|
// Hence, raising these events with wxEVT_CHILD_FOCUS events.
|
|
//
|
|
#ifdef __WXMAC__
|
|
|
|
datValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this);
|
|
timValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this);
|
|
|
|
#endif
|
|
|
|
if (connection->BackendMinimumVersion(9, 0))
|
|
{
|
|
cbVarDbname->Append(wxT(""));
|
|
AddDatabases(cbVarDbname);
|
|
}
|
|
else
|
|
{
|
|
cbVarDbname->Enable(false);
|
|
}
|
|
|
|
if (connection->BackendMinimumVersion(9, 2))
|
|
{
|
|
seclabelPage->SetConnection(connection);
|
|
seclabelPage->SetObject(role);
|
|
this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgRole::OnChange));
|
|
}
|
|
else
|
|
seclabelPage->Disable();
|
|
|
|
wxString roleSql =
|
|
wxT("SELECT rolname\n")
|
|
wxT(" FROM pg_roles r\n");
|
|
|
|
varInfo.Add(wxT("role"));
|
|
cbVarname->Append(wxT("role"));
|
|
|
|
pgSet *set;
|
|
set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n")
|
|
wxT(" FROM pg_settings WHERE context in ('user', 'superuser')"));
|
|
|
|
if (set)
|
|
{
|
|
while (!set->Eof())
|
|
{
|
|
cbVarname->Append(set->GetVal(0));
|
|
varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") +
|
|
set->GetVal(wxT("min_val")) + wxT(" ") +
|
|
set->GetVal(wxT("max_val")));
|
|
set->MoveNext();
|
|
}
|
|
delete set;
|
|
|
|
cbVarname->SetSelection(0);
|
|
|
|
if (connection->BackendMinimumVersion(9, 0))
|
|
{
|
|
cbVarDbname->SetSelection(0);
|
|
}
|
|
|
|
SetupVarEditor(0);
|
|
}
|
|
|
|
if (role)
|
|
{
|
|
wxArrayString roles = role->GetRolesIn();
|
|
size_t i;
|
|
for (i = 0 ; i < roles.GetCount() ; i++)
|
|
lbRolesIn->Append(roles.Item(i));
|
|
|
|
roleSql +=
|
|
wxT(" LEFT JOIN pg_auth_members ON r.oid=roleid AND member = ") + role->GetOidStr() + wxT("\n")
|
|
wxT(" WHERE r.oid <> ") + role->GetOidStr() + wxT("\n")
|
|
wxT(" AND roleid IS NULL");
|
|
|
|
// Edit Mode
|
|
if (role->GetServer()->GetSuperUser() || role->GetServer()->GetCreateRole())
|
|
readOnly = false;
|
|
else
|
|
readOnly = true;
|
|
|
|
chkCreateDB->SetValue(role->GetCreateDatabase());
|
|
chkCreateRole->SetValue(role->GetCreateRole());
|
|
chkSuperuser->SetValue(role->GetSuperuser());
|
|
chkInherits->SetValue(role->GetInherits());
|
|
if (!connection->BackendMinimumVersion(9, 5))
|
|
chkUpdateCat->SetValue(role->GetUpdateCatalog());
|
|
else
|
|
chkUpdateCat->Disable();
|
|
chkCanLogin->SetValue(role->GetCanLogin());
|
|
chkReplication->SetValue(role->GetReplication());
|
|
if (role->GetAccountExpires().IsValid() && role->GetAccountExpires().GetValue() != -1)
|
|
{
|
|
datValidUntil->SetValue(role->GetAccountExpires().GetDateOnly());
|
|
timValidUntil->SetTime(role->GetAccountExpires());
|
|
}
|
|
else
|
|
{
|
|
wxDateTime empty;
|
|
datValidUntil->SetValue(empty);
|
|
}
|
|
txtConnectionLimit->SetValue(NumToStr(role->GetConnectionLimit()));
|
|
txtComment->SetValue(role->GetComment());
|
|
|
|
size_t index;
|
|
wxString dbname;
|
|
wxString parameter;
|
|
wxString value;
|
|
for (index = 0 ; index < role->GetVariables().GetCount() ; index += 3)
|
|
{
|
|
dbname = role->GetVariables().Item(index);
|
|
parameter = role->GetVariables().Item(index + 1);
|
|
value = role->GetVariables().Item(index + 2);
|
|
|
|
lstVariables->AppendItem(0, dbname, parameter, value);
|
|
}
|
|
|
|
timValidUntil->Enable(!readOnly && role->GetAccountExpires().IsValid());
|
|
|
|
if (readOnly)
|
|
{
|
|
chkCanLogin->Disable();
|
|
chkCreateDB->Disable();
|
|
chkCreateRole->Disable();
|
|
chkSuperuser->Disable();
|
|
chkInherits->Disable();
|
|
chkUpdateCat->Disable();
|
|
chkReplication->Disable();
|
|
datValidUntil->Disable();
|
|
timValidUntil->Disable();
|
|
btnAddRole->Disable();
|
|
btnDelRole->Disable();
|
|
cbVarname->Disable();
|
|
cbVarDbname->Disable();
|
|
txtValue->Disable();
|
|
txtConnectionLimit->Disable();
|
|
btnRemove->Disable();
|
|
/* Its own password can be changed. */
|
|
if (connection->GetUser() != role->GetName())
|
|
{
|
|
txtPasswd->Disable();
|
|
txtRePasswd->Disable();
|
|
btnAdd->Disable();
|
|
}
|
|
else
|
|
{
|
|
txtPasswd->Enable();
|
|
txtRePasswd->Enable();
|
|
btnAdd->Enable();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
chkCanLogin->Disable();
|
|
wxDateTime empty;
|
|
datValidUntil->SetValue(empty);
|
|
timValidUntil->Disable();
|
|
}
|
|
|
|
// Role comments are only appropriate in 8.2+
|
|
if (!connection->BackendMinimumVersion(8, 2))
|
|
txtComment->Disable();
|
|
|
|
// Replication roles added in 9.1
|
|
if (!connection->BackendMinimumVersion(9, 1))
|
|
{
|
|
chkReplication->Disable();
|
|
}
|
|
|
|
|
|
if (!settings->GetShowUsersForPrivileges())
|
|
{
|
|
if (role)
|
|
roleSql += wxT("\n AND NOT rolcanlogin");
|
|
else
|
|
roleSql += wxT("\n WHERE NOT rolcanlogin");
|
|
}
|
|
roleSql += wxT("\n ORDER BY rolname");
|
|
|
|
pgSetIterator roles(connection, roleSql);
|
|
|
|
while (roles.RowsLeft())
|
|
lbRolesNotIn->Append(roles.GetVal(wxT("rolname")));
|
|
|
|
return dlgProperty::Go(modal);
|
|
}
|
|
|
|
|
|
wxString dlgRole::GetHelpPage() const
|
|
{
|
|
if (nbNotebook->GetSelection() == 2)
|
|
return wxT("pg/runtime-config");
|
|
else
|
|
return wxT("pg/sql-createrole");
|
|
}
|
|
|
|
|
|
void dlgRole::OnOK(wxCommandEvent &ev)
|
|
{
|
|
dlgProperty::OnOK(ev);
|
|
|
|
if (role && ((role->GetCanLogin() != chkCanLogin->GetValue()) == !btnOK->IsEnabled()))
|
|
{
|
|
// LOGIN attribute changed successfully; need to put object under different collection
|
|
}
|
|
}
|
|
|
|
|
|
void dlgRole::OnChangeCal(wxCalendarEvent &ev)
|
|
{
|
|
bool timEn = ev.GetDate().IsValid();
|
|
timValidUntil->Enable(timEn);
|
|
if (!timEn)
|
|
timValidUntil->SetTime(wxDefaultDateTime);
|
|
else
|
|
timValidUntil->SetTime(wxDateTime::Today());
|
|
|
|
CheckChange();
|
|
}
|
|
|
|
|
|
void dlgRole::OnChangeDate(wxDateEvent &ev)
|
|
{
|
|
bool timEn = ev.GetDate().IsValid();
|
|
timValidUntil->Enable(timEn);
|
|
if (!timEn)
|
|
timValidUntil->SetTime(wxDefaultDateTime);
|
|
else
|
|
timValidUntil->SetTime(wxDateTime::Today());
|
|
|
|
CheckChange();
|
|
}
|
|
|
|
void dlgRole::OnChangeSpin(wxSpinEvent &ev)
|
|
{
|
|
CheckChange();
|
|
}
|
|
|
|
|
|
void dlgRole::OnChangeSuperuser(wxCommandEvent &ev)
|
|
{
|
|
if (role && role->GetSuperuser() && !chkSuperuser->GetValue())
|
|
{
|
|
wxMessageDialog dlg(this,
|
|
_("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"),
|
|
_("Confirm superuser deletion"),
|
|
wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT);
|
|
if (dlg.ShowModal() != wxID_YES)
|
|
{
|
|
chkSuperuser->SetValue(true);
|
|
return;
|
|
}
|
|
}
|
|
chkUpdateCat->SetValue(chkSuperuser->GetValue() &&
|
|
!connection->BackendMinimumVersion(9, 5));
|
|
CheckChange();
|
|
}
|
|
|
|
void dlgRole::OnChangePasswd(wxCommandEvent &ev)
|
|
{
|
|
CheckChange();
|
|
}
|
|
|
|
void dlgRole::CheckChange()
|
|
{
|
|
bool enable = true;
|
|
bool timEn = datValidUntil->GetValue().IsValid();
|
|
timValidUntil->Enable(timEn);
|
|
if (!timEn)
|
|
timValidUntil->SetTime(wxDefaultDateTime);
|
|
|
|
if (!readOnly)
|
|
chkUpdateCat->Enable(chkSuperuser->GetValue() &&
|
|
!connection->BackendMinimumVersion(9, 5));
|
|
|
|
// Check the passwords match
|
|
if (txtPasswd->GetValue() != txtRePasswd->GetValue())
|
|
{
|
|
bool enable = true;
|
|
CheckValid(enable, false, _("The passwords entered do not match!"));
|
|
EnableOK(enable);
|
|
return;
|
|
}
|
|
|
|
if (!role)
|
|
{
|
|
wxString name = GetName();
|
|
CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
|
|
}
|
|
else
|
|
{
|
|
enable = !GetSql().IsEmpty();
|
|
if (seclabelPage && connection->BackendMinimumVersion(9, 2))
|
|
enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty());
|
|
}
|
|
EnableOK(enable);
|
|
}
|
|
|
|
|
|
void dlgRole::OnRoleAdd(wxCommandEvent &ev)
|
|
{
|
|
if (!readOnly)
|
|
{
|
|
int pos = lbRolesNotIn->GetSelection();
|
|
if (pos >= 0)
|
|
{
|
|
wxString roleName = lbRolesNotIn->GetString(pos);
|
|
if (chkAdminOption->GetValue())
|
|
roleName += "(A)";
|
|
lbRolesIn->Append(roleName);
|
|
lbRolesNotIn->Delete(pos);
|
|
}
|
|
CheckChange();
|
|
}
|
|
}
|
|
|
|
|
|
void dlgRole::OnRoleRemove(wxCommandEvent &ev)
|
|
{
|
|
if (!readOnly)
|
|
{
|
|
int pos = lbRolesIn->GetSelection();
|
|
if (pos >= 0)
|
|
{
|
|
wxString roleName = lbRolesIn->GetString(pos);
|
|
if (!pgRole::GetOptStr(roleName).IsEmpty())
|
|
roleName = roleName.BeforeLast('(');
|
|
|
|
lbRolesNotIn->Append(roleName);
|
|
lbRolesIn->Delete(pos);
|
|
}
|
|
CheckChange();
|
|
}
|
|
}
|
|
|
|
|
|
void dlgRole::OnVarnameSelChange(wxCommandEvent &ev)
|
|
{
|
|
int sel = cbVarname->GuessSelection(ev);
|
|
|
|
SetupVarEditor(sel);
|
|
}
|
|
|
|
void dlgRole::SetupVarEditor(int var)
|
|
{
|
|
if (var >= 0 && varInfo.Count() > 0)
|
|
{
|
|
wxStringTokenizer vals(varInfo.Item(var));
|
|
wxString typ = vals.GetNextToken();
|
|
|
|
if (typ == wxT("bool"))
|
|
{
|
|
txtValue->Hide();
|
|
chkValue->Show();
|
|
chkValue->GetParent()->Layout();
|
|
}
|
|
else
|
|
{
|
|
chkValue->Hide();
|
|
txtValue->Show();
|
|
txtValue->GetParent()->Layout();
|
|
if (typ == wxT("string") || typ == wxT("enum"))
|
|
txtValue->SetValidator(wxTextValidator());
|
|
else
|
|
txtValue->SetValidator(numericValidator);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void dlgRole::OnVarSelChange(wxListEvent &ev)
|
|
{
|
|
long pos = lstVariables->GetSelection();
|
|
if (pos >= 0)
|
|
{
|
|
cbVarDbname->SetValue(lstVariables->GetText(pos));
|
|
cbVarname->SetValue(lstVariables->GetText(pos, 1));
|
|
|
|
// We used to raise an OnVarnameSelChange() event here, but
|
|
// at this point the combo box hasn't necessarily updated.
|
|
wxString value = lstVariables->GetText(pos, 2);
|
|
int sel = cbVarname->FindString(lstVariables->GetText(pos, 1));
|
|
|
|
txtValue->SetValue(value);
|
|
chkValue->SetValue(value == wxT("on"));
|
|
}
|
|
}
|
|
|
|
|
|
void dlgRole::OnVarAdd(wxCommandEvent &ev)
|
|
{
|
|
wxString dbname = cbVarDbname->GetValue();
|
|
wxString name = cbVarname->GetValue();
|
|
wxString value;
|
|
if (chkValue->IsShown())
|
|
value = chkValue->GetValue() ? wxT("on") : wxT("off");
|
|
else
|
|
value = txtValue->GetValue().Strip(wxString::both);
|
|
|
|
if (value.IsEmpty())
|
|
value = wxT("DEFAULT");
|
|
|
|
if (!name.IsEmpty())
|
|
{
|
|
bool found = false;
|
|
long prevpos = -1;
|
|
for (long item = 0; item < lstVariables->GetItemCount(); item++)
|
|
{
|
|
if (name == lstVariables->GetText(item, 1))
|
|
{
|
|
if (dbname == lstVariables->GetText(item))
|
|
{
|
|
found = true;
|
|
lstVariables->SetItem(item, 2, value);
|
|
}
|
|
else
|
|
{
|
|
prevpos = item;
|
|
}
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
if (prevpos != -1)
|
|
{
|
|
lstVariables->InsertItem(prevpos, dbname, 1);
|
|
lstVariables->SetItem(prevpos, 1, name);
|
|
lstVariables->SetItem(prevpos, 2, value);
|
|
}
|
|
else
|
|
{
|
|
long pos = lstVariables->GetItemCount();
|
|
lstVariables->InsertItem(pos, dbname, 1);
|
|
lstVariables->SetItem(pos, 1, name);
|
|
lstVariables->SetItem(pos, 2, value);
|
|
}
|
|
}
|
|
}
|
|
CheckChange();
|
|
}
|
|
|
|
|
|
void dlgRole::OnVarRemove(wxCommandEvent &ev)
|
|
{
|
|
if (lstVariables->GetSelection() == wxNOT_FOUND)
|
|
return;
|
|
lstVariables->DeleteCurrentItem();
|
|
CheckChange();
|
|
}
|
|
|
|
|
|
pgObject *dlgRole::CreateObject(pgCollection *collection)
|
|
{
|
|
wxString name = GetName();
|
|
|
|
pgObject *obj = loginRoleFactory.CreateObjects(collection, 0, wxT("\n WHERE rolname=") + qtDbString(name));
|
|
return obj;
|
|
}
|
|
|
|
|
|
wxString dlgRole::GetSql()
|
|
{
|
|
int pos;
|
|
wxString sql;
|
|
wxString name = GetName();
|
|
|
|
wxString passwd = txtPasswd->GetValue();
|
|
bool createDB = chkCreateDB->GetValue(),
|
|
createRole = chkCreateRole->GetValue(),
|
|
superuser = chkSuperuser->GetValue(),
|
|
inherits = chkInherits->GetValue(),
|
|
canLogin = chkCanLogin->GetValue(),
|
|
replication = chkReplication->GetValue();
|
|
|
|
if (role)
|
|
{
|
|
// Edit Mode
|
|
|
|
AppendNameChange(sql, wxT("ROLE ") + role->GetQuotedFullIdentifier());
|
|
|
|
|
|
wxString options;
|
|
if (canLogin != role->GetCanLogin())
|
|
{
|
|
if (canLogin)
|
|
options = wxT(" LOGIN");
|
|
else
|
|
options = wxT(" NOLOGIN");
|
|
}
|
|
if (canLogin && !passwd.IsEmpty())
|
|
options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd));
|
|
|
|
if (createDB != role->GetCreateDatabase() || createRole != role->GetCreateRole()
|
|
|| superuser != role->GetSuperuser() || inherits != role->GetInherits()
|
|
|| replication != role->GetReplication())
|
|
{
|
|
options += wxT("\n ");
|
|
|
|
if (superuser != role->GetSuperuser())
|
|
{
|
|
if (superuser)
|
|
options += wxT(" SUPERUSER");
|
|
else
|
|
options += wxT(" NOSUPERUSER");
|
|
}
|
|
if (inherits != role->GetInherits())
|
|
{
|
|
if (inherits)
|
|
options += wxT(" INHERIT");
|
|
else
|
|
options += wxT(" NOINHERIT");
|
|
}
|
|
if (createDB != role->GetCreateDatabase())
|
|
{
|
|
if (createDB)
|
|
options += wxT(" CREATEDB");
|
|
else
|
|
options += wxT(" NOCREATEDB");
|
|
}
|
|
if (createRole != role->GetCreateRole())
|
|
{
|
|
if (createRole)
|
|
options += wxT(" CREATEROLE");
|
|
else
|
|
options += wxT(" NOCREATEROLE");
|
|
}
|
|
if (connection->BackendMinimumVersion(9, 1))
|
|
{
|
|
if (replication != role->GetReplication())
|
|
{
|
|
if (replication)
|
|
options += wxT(" REPLICATION");
|
|
else
|
|
options += wxT(" NOREPLICATION");
|
|
}
|
|
}
|
|
}
|
|
if (!datValidUntil->GetValue().IsValid() || DateToStr(datValidUntil->GetValue() + timValidUntil->GetValue()) != DateToStr(role->GetAccountExpires()))
|
|
{
|
|
if (datValidUntil->GetValue().IsValid())
|
|
options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue()));
|
|
else if (!role->GetIsValidInfinity() && role->GetAccountExpires().GetValue() != -1)
|
|
options += wxT("\n VALID UNTIL 'infinity'");
|
|
}
|
|
|
|
if (txtConnectionLimit->GetValue().Length() == 0)
|
|
{
|
|
if (role->GetConnectionLimit() != -1)
|
|
{
|
|
options += wxT(" CONNECTION LIMIT -1");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (txtConnectionLimit->GetValue() != NumToStr(role->GetConnectionLimit()))
|
|
{
|
|
options += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue();
|
|
}
|
|
}
|
|
|
|
if (!options.IsNull())
|
|
sql += wxT("ALTER ROLE ") + qtIdent(name) + options + wxT(";\n");
|
|
|
|
if (!connection->BackendMinimumVersion(9, 5) &&
|
|
chkUpdateCat->GetValue() != role->GetUpdateCatalog())
|
|
{
|
|
if (!connection->HasPrivilege(wxT("Table"), wxT("pg_authid"), wxT("update")))
|
|
sql += wxT(" -- Can't update 'UpdateCatalog privilege: can't write to pg_authid.\n")
|
|
wxT("-- ");
|
|
|
|
sql += wxT("UPDATE pg_authid SET rolcatupdate=") + BoolToStr(chkUpdateCat->GetValue())
|
|
+ wxT(" WHERE OID=") + role->GetOidStr() + wxT(";\n");
|
|
}
|
|
int cnt = lbRolesIn->GetCount();
|
|
wxArrayString tmpRoles = role->GetRolesIn();
|
|
|
|
// check for added roles
|
|
for (pos = 0 ; pos < cnt ; pos++)
|
|
{
|
|
wxString roleName = lbRolesIn->GetString(pos);
|
|
|
|
int index = tmpRoles.Index(roleName);
|
|
if (index >= 0)
|
|
{
|
|
// role membership unchanged
|
|
tmpRoles.RemoveAt(index);
|
|
}
|
|
else
|
|
{
|
|
bool admin = false;
|
|
wxString opt = pgRole::GetOptStr(roleName);
|
|
if (!opt.IsEmpty())
|
|
{
|
|
admin = true;
|
|
roleName = roleName.BeforeLast('(');
|
|
}
|
|
else
|
|
{
|
|
// new role membership without admin option
|
|
index = tmpRoles.Index(roleName + "(");
|
|
if (index >= 0)
|
|
{
|
|
// old membership with admin option
|
|
tmpRoles.RemoveAt(index);
|
|
sql += wxT("REVOKE ADMIN OPTION FOR ") + qtIdent(roleName)
|
|
+ wxT(" FROM ") + qtIdent(name) + wxT(";\n");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
index = tmpRoles.Index(roleName);
|
|
if (index >= 0)
|
|
{
|
|
// admin option added to existing membership
|
|
tmpRoles.RemoveAt(index);
|
|
}
|
|
|
|
sql += wxT("GRANT ") + qtIdent(roleName)
|
|
+ wxT(" TO ") + qtIdent(name);
|
|
|
|
if (admin)
|
|
sql += opt;
|
|
|
|
sql += wxT(";\n");
|
|
}
|
|
}
|
|
|
|
// check for removed roles
|
|
for (pos = 0 ; pos < (int)tmpRoles.GetCount() ; pos++)
|
|
{
|
|
wxString roleName = tmpRoles.Item(pos);
|
|
wxString opt=pgRole::GetOptStr(roleName);
|
|
if (!opt.IsEmpty()) roleName = roleName.BeforeLast('(');
|
|
|
|
sql += wxT("REVOKE ") + qtIdent(roleName)
|
|
+ wxT(" FROM ") + qtIdent(name) + wxT(";\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Create Mode
|
|
sql = wxT(
|
|
"CREATE ROLE ") + qtIdent(name);
|
|
if (canLogin)
|
|
{
|
|
sql += wxT(" LOGIN");
|
|
if (!passwd.IsEmpty())
|
|
sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd));
|
|
}
|
|
|
|
if (createDB || createRole || !inherits || superuser)
|
|
sql += wxT("\n ");
|
|
if (superuser)
|
|
sql += wxT(" SUPERUSER");
|
|
if (!inherits)
|
|
sql += wxT(" NOINHERIT");
|
|
if (createDB)
|
|
sql += wxT(" CREATEDB");
|
|
if (createRole)
|
|
sql += wxT(" CREATEROLE");
|
|
if (connection->BackendMinimumVersion(9, 1))
|
|
{
|
|
if (replication)
|
|
sql += wxT(" REPLICATION");
|
|
}
|
|
if (datValidUntil->GetValue().IsValid())
|
|
sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue()));
|
|
else
|
|
sql += wxT("\n VALID UNTIL 'infinity'");
|
|
|
|
if (txtConnectionLimit->GetValue().Length() > 0)
|
|
{
|
|
sql += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue();
|
|
}
|
|
|
|
int cnt = lbRolesIn->GetCount();
|
|
wxString grants;
|
|
|
|
if (cnt)
|
|
{
|
|
wxString roleName;
|
|
|
|
for (pos = 0 ; pos < cnt ; pos++)
|
|
{
|
|
bool admin = false;
|
|
roleName = lbRolesIn->GetString(pos);
|
|
wxString opt = pgRole::GetOptStr(roleName);
|
|
if (!opt.IsEmpty())
|
|
{
|
|
roleName = roleName.BeforeLast('(');
|
|
admin = true;
|
|
|
|
}
|
|
grants += wxT("GRANT ") + qtIdent(roleName)
|
|
+ wxT(" TO ") + qtIdent(name);
|
|
|
|
if (admin)
|
|
grants += opt;
|
|
else
|
|
grants += wxT(";\n");
|
|
}
|
|
}
|
|
sql += wxT(";\n") + grants;
|
|
|
|
if (superuser && !chkUpdateCat->GetValue() &&
|
|
!connection->BackendMinimumVersion(9, 5))
|
|
sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(name) + wxT(";\n");
|
|
}
|
|
|
|
wxArrayString vars;
|
|
wxString dbname;
|
|
wxString parameter;
|
|
wxString value;
|
|
|
|
size_t index;
|
|
|
|
if (role)
|
|
{
|
|
for (index = 0 ; index < role->GetVariables().GetCount() ; index++)
|
|
vars.Add(role->GetVariables().Item(index));
|
|
}
|
|
|
|
int cnt = lstVariables->GetItemCount();
|
|
|
|
// check for changed or added vars
|
|
for (pos = 0 ; pos < cnt ; pos++)
|
|
{
|
|
wxString newDb = lstVariables->GetText(pos);
|
|
wxString newVar = lstVariables->GetText(pos, 1);
|
|
wxString newVal = lstVariables->GetText(pos, 2);
|
|
|
|
wxString oldVal;
|
|
|
|
for (index = 0 ; index < vars.GetCount() ; index += 3)
|
|
{
|
|
dbname = vars.Item(index);
|
|
parameter = vars.Item(index + 1);
|
|
value = vars.Item(index + 2);
|
|
|
|
if (newDb == dbname && newVar == parameter)
|
|
{
|
|
oldVal = value;
|
|
vars.RemoveAt(index);
|
|
vars.RemoveAt(index);
|
|
vars.RemoveAt(index);
|
|
break;
|
|
}
|
|
}
|
|
if (oldVal != newVal)
|
|
{
|
|
if (newDb.Length() == 0)
|
|
sql += wxT("ALTER ROLE ") + qtIdent(name);
|
|
else
|
|
sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + newDb;
|
|
|
|
if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces"))
|
|
{
|
|
sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n");
|
|
}
|
|
else
|
|
{
|
|
sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for removed vars
|
|
for (pos = 0 ; pos < (int)vars.GetCount() ; pos += 3)
|
|
{
|
|
dbname = vars.Item(pos);
|
|
parameter = vars.Item(pos + 1);
|
|
value = vars.Item(pos + 2);
|
|
|
|
if (dbname.Length() == 0)
|
|
{
|
|
sql += wxT("ALTER ROLE ") + qtIdent(name)
|
|
+ wxT(" RESET ") + parameter
|
|
+ wxT(";\n");
|
|
}
|
|
else
|
|
{
|
|
sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + dbname
|
|
+ wxT(" RESET ") + parameter + wxT(";\n");
|
|
}
|
|
}
|
|
|
|
AppendComment(sql, wxT("ROLE"), 0, role);
|
|
|
|
if (seclabelPage && connection->BackendMinimumVersion(9, 2))
|
|
sql += seclabelPage->GetSqlForSecLabels(wxT("ROLE"), qtIdent(name));
|
|
|
|
return sql;
|
|
}
|
|
|
|
|
|
void dlgRole::OnChange(wxCommandEvent &event)
|
|
{
|
|
CheckChange();
|
|
}
|