diff --git a/pgadmin/ctl/ctlSeclabelPanel.cpp b/pgadmin/ctl/ctlSeclabelPanel.cpp index a5be9a1..0c4a669 100644 --- a/pgadmin/ctl/ctlSeclabelPanel.cpp +++ b/pgadmin/ctl/ctlSeclabelPanel.cpp @@ -29,6 +29,8 @@ BEGIN_EVENT_TABLE(ctlSeclabelPanel, wxPanel) EVT_LIST_ITEM_SELECTED(CTL_LBSECLABEL, ctlSeclabelPanel::OnSeclabelSelChange) EVT_BUTTON(CTL_ADDSECLABEL, ctlSeclabelPanel::OnAddSeclabel) EVT_BUTTON(CTL_DELSECLABEL, ctlSeclabelPanel::OnDelSeclabel) + EVT_TEXT(CTL_PROVIDER, ctlSeclabelPanel::OnChange) + EVT_TEXT(CTL_SECLABEL, ctlSeclabelPanel::OnChange) END_EVENT_TABLE(); DEFINE_LOCAL_EVENT_TYPE(EVT_SECLABELPANEL_CHANGE) @@ -84,6 +86,8 @@ ctlSeclabelPanel::ctlSeclabelPanel(wxNotebook *nb) // compute sizes this->SetSizer(sizer0); sizer0->Fit(this); + + btnAddSeclabel->Enable(false); } @@ -101,7 +105,6 @@ void ctlSeclabelPanel::Disable() txtSeclabel->Disable(); } - void ctlSeclabelPanel::SetConnection(pgConn *conn) { connection = conn; @@ -170,6 +173,12 @@ void ctlSeclabelPanel::OnAddSeclabel(wxCommandEvent &ev) ev.Skip(); } +void ctlSeclabelPanel::OnChange(wxCommandEvent &event) +{ + wxString provider = txtProvider->GetValue().Trim(true).Trim(false); + wxString label = txtSeclabel->GetValue().Trim(true).Trim(false); + btnAddSeclabel->Enable(!provider.IsEmpty() && !label.IsEmpty()); +} void ctlSeclabelPanel::OnSeclabelSelChange(wxListEvent &ev) { @@ -180,6 +189,14 @@ void ctlSeclabelPanel::OnSeclabelSelChange(wxListEvent &ev) txtSeclabel->SetValue(lbSeclabels->GetText(lbSeclabels->GetSelection(), 1)); } +void ctlSeclabelPanel::GetCurrentProviderLabelArray(wxArrayString& secLabels) +{ + for(int indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + secLabels.Add(lbSeclabels->GetText(indexList)); + secLabels.Add(lbSeclabels->GetText(indexList,1)); + } +} wxString ctlSeclabelPanel::GetSqlForSecLabels(wxString objecttype, wxString objectname) { @@ -270,4 +287,4 @@ wxString ctlSeclabelPanel::GetSqlForSecLabels(wxString objecttype, wxString obje } return sql; -} +} \ No newline at end of file diff --git a/pgadmin/ctl/ctlSecurityPanel.cpp b/pgadmin/ctl/ctlSecurityPanel.cpp index 8c46e12..9899d7a 100644 --- a/pgadmin/ctl/ctlSecurityPanel.cpp +++ b/pgadmin/ctl/ctlSecurityPanel.cpp @@ -147,14 +147,12 @@ ctlSecurityPanel::ctlSecurityPanel(wxNotebook *nb, const wxString &privList, con item0->Fit(this); } - ctlSecurityPanel::~ctlSecurityPanel() { if (privCheckboxes) delete[] privCheckboxes; } - void ctlSecurityPanel::SetConnection(pgConn *conn) { connection = conn; @@ -162,6 +160,26 @@ void ctlSecurityPanel::SetConnection(pgConn *conn) stGroup->SetLabel(_("Role")); } +wxString ctlSecurityPanel::GetUserPrivileges() +{ + wxString strPrivilages = wxEmptyString; + int cnt = lbPrivileges->GetItemCount(); + int pos; + if(cnt > 0) + { + strPrivilages += wxT("{"); + for (pos = 0 ; pos < cnt ; pos++) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + strPrivilages += (pos == 0) ? name + wxT("=") + value : wxT(",") + name + wxT("=") + value; + strPrivilages += wxT("/") + connection->GetUser(); + } + strPrivilages += wxT("}"); + } + return strPrivilages; +} wxString ctlSecurityPanel::GetGrant(const wxString &allPattern, const wxString &grantObject, wxArrayString *currentAcl, wxString column) { diff --git a/pgadmin/dlg/dlgColumn.cpp b/pgadmin/dlg/dlgColumn.cpp index 7df7930..4c7d147 100644 --- a/pgadmin/dlg/dlgColumn.cpp +++ b/pgadmin/dlg/dlgColumn.cpp @@ -112,71 +112,7 @@ dlgColumn::dlgColumn(pgaFactory *f, frmMain *frame, pgColumn *node, pgTable *par delete setGrp; } - if (node) - { - wxString strAcl = node->GetAcl(); - if (!strAcl.IsEmpty()) - { - wxArrayString aclArray; - strAcl = strAcl.Mid(1, strAcl.Length() - 2); - getArrayFromCommaSeparatedList(strAcl, aclArray); - wxString roleName; - for (unsigned int index = 0; index < aclArray.Count(); index++) - { - wxString strCurrAcl = aclArray[index]; - - /* - * In rare case, we can have ',' (comma) in the user name. - * But, we need to handle them also - */ - if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) - { - // Check it is start of the ACL - if (strCurrAcl[0U] == (wxChar)'"') - roleName = strCurrAcl + wxT(","); - continue; - } - else - strCurrAcl = roleName + strCurrAcl; - - if (strCurrAcl[0U] == (wxChar)'"') - strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); - roleName = strCurrAcl.BeforeLast('='); - - wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); - - int icon = userFactory.GetIconId(); - - if (roleName.Left(6).IsSameAs(wxT("group "), false)) - { - icon = groupFactory.GetIconId(); - roleName = wxT("group ") + qtStrip(roleName.Mid(6)); - } - else if (roleName.IsEmpty()) - { - icon = PGICON_PUBLIC; - roleName = wxT("public"); - } - else - { - roleName = qtStrip(roleName); - for (unsigned int index = 0; index < groups.Count(); index++) - if (roleName == groups[index]) - { - roleName = wxT("group ") + roleName; - icon = groupFactory.GetIconId(); - break; - } - } - - securityPage->lbPrivileges->AppendItem(icon, roleName, value); - currentAcl.Add(roleName + wxT("=") + value); - - // Reset roleName - roleName.Empty(); - } - } - } + SetSecurityPage(node); } else securityPage->Disable(); @@ -202,6 +138,77 @@ pgObject *dlgColumn::GetObject() return column; } +void dlgColumn::SetSecurityPage(const pgColumn* node) +{ + if (node) + { + wxString strAcl = node->GetAcl(); + securityPage->lbPrivileges->DeleteAllItems(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + + if(changedColumn == NULL) + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } +} int dlgColumn::Go(bool modal) { @@ -630,6 +637,40 @@ void dlgColumn::ApplyChangesToObj(pgColumn *changedCol) { changedCol->GetVariables().Add(lstVariables->GetText(pos) + wxT("=") + lstVariables->GetText(pos, 1)); } + + if(securityPage && connection->BackendMinimumVersion(8, 4)) + { + changedCol->iSetAcl(securityPage->GetUserPrivileges()); + } + + if(seclabelPage && connection->BackendMinimumVersion(9, 1)) + { + wxArrayString secLabels; + wxString providers; + wxString labels; + seclabelPage->GetCurrentProviderLabelArray(secLabels); + + if(!secLabels.IsEmpty()) + { + for(size_t pos = 0; pos < secLabels.Count(); pos += 2) + { + if(pos == 0) + { + providers += wxT("{") + secLabels.Item(pos); + labels += wxT("{") + secLabels.Item(pos+1); + } + else + { + providers += wxT(",") + secLabels.Item(pos); + labels += wxT(",") + secLabels.Item(pos+1); + } + } + providers += wxT("}"); + labels += wxT("}"); + } + changedCol->iSetProviders(providers); + changedCol->iSetLabels(labels); + } } @@ -655,8 +696,43 @@ void dlgColumn::ApplyChangesToDlg() wxString item = changedColumn->GetVariables().Item(i); lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); } + + //setting privileges to changed values + SetSecurityPage(changedColumn); + + if (connection->BackendMinimumVersion(9, 1)) + { + wxArrayString seclabels = changedColumn->GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + seclabelPage->lbSeclabels->AppendItem(seclabels.Item(index), + seclabels.Item(index + 1)); + } + } + } + else + seclabelPage->Disable(); +} + +void dlgColumn::GetVariableList(wxArrayString& variableList) +{ + wxString name; + wxString value; + for(int pos = 0; pos < lstVariables->GetItemCount(); pos++) + { + name = lstVariables->GetText(pos); + value = lstVariables->GetText(pos, 1); + variableList.Add(name + wxT("=") + value); + } } +void dlgColumn::GetSecLabelList(wxArrayString& secLabelList) +{ + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + seclabelPage->GetCurrentProviderLabelArray(secLabelList); +} wxString dlgColumn::GetDefinition() { diff --git a/pgadmin/dlg/dlgTable.cpp b/pgadmin/dlg/dlgTable.cpp index 9f7a565..843fe33 100644 --- a/pgadmin/dlg/dlgTable.cpp +++ b/pgadmin/dlg/dlgTable.cpp @@ -200,7 +200,10 @@ dlgTable::dlgTable(pgaFactory *f, frmMain *frame, pgTable *node, pgSchema *sch) lstColumns->AddColumn(_("Column type oid"), 0); // ... pgColumn* handle (used for changed columns) lstColumns->AddColumn(_("Changed column"), 0); - + // ... pgColumn* handle (used for variable list) + lstColumns->AddColumn(_("Variable List"), 0); + // ... pgColumn* handle (used for security label list) + lstColumns->AddColumn(_("Security Label List"), 0); lstConstraints->CreateColumns(0, _("Constraint name"), _("Definition"), 90); } @@ -212,6 +215,16 @@ dlgTable::~dlgTable() delete dtCache.Item(i); } +bool dlgTable::Destroy() +{ + for(int pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + pgColumn *column2 = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_CHANGEDCOL)); + if(column2) delete column2; + } + return dlgProperty::Destroy(); +} + pgObject *dlgTable::GetObject() { return table; @@ -1416,7 +1429,6 @@ wxString dlgTable::GetSql() AppendOwnerNew(sql, wxT("TABLE ") + tabname); // Extra column info - // Statistics for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) { @@ -1428,6 +1440,38 @@ wxString dlgTable::GetSql() } } + //variables + for (pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + wxStringTokenizer varToken(lstColumns->GetText(pos,COL_VARIABLE_LIST),wxT(",")); + while (varToken.HasMoreTokens()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n ALTER COLUMN ") + + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT(" \nSET ("); + sql += varToken.GetNextToken() + wxT(");\n"); + } + } + + //security labels + for (pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + wxStringTokenizer varToken(lstColumns->GetText(pos,COL_SECLABEL_LIST),wxT(",")); + wxString providerLabel = wxEmptyString; + wxString provider = wxEmptyString; + while (varToken.HasMoreTokens()) + { + provider = varToken.GetNextToken(); + if(varToken.HasMoreTokens()) + providerLabel = varToken.GetNextToken(); + + sql += wxT("SECURITY LABEL FOR ") + provider + + wxT("\n ON COLUMN ") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT("\n IS ") + connection->qtDbString(providerLabel) + wxT(";\n"); + } + } + // Comments for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) { @@ -1801,16 +1845,16 @@ void dlgTable::OnChangeCol(wxCommandEvent &ev) col.SetChangedCol(column2); if (col.Go(true) != wxID_CANCEL) { - delete column2; - pgColumn *changedColumn = new pgColumn(* column); - col.ApplyChangesToObj(changedColumn); + if(column2 == NULL) + column2 = new pgColumn(*column); + col.ApplyChangesToObj(column2); lstColumns->SetItem(pos, COL_NAME, col.GetName()); lstColumns->SetItem(pos, COL_DEFINITION, col.GetDefinition()); lstColumns->SetItem(pos, COL_SQLCHANGE, col.GetSql()); lstColumns->SetItem(pos, COL_STATISTICS, col.GetStatistics()); lstColumns->SetItem(pos, COL_COMMENTS, col.GetComment()); - lstColumns->SetItem(pos, COL_CHANGEDCOL, NumToStr((long)changedColumn)); + lstColumns->SetItem(pos, COL_CHANGEDCOL, NumToStr((long)column2)); } CheckChange(); } @@ -1847,6 +1891,36 @@ void dlgTable::OnAddCol(wxCommandEvent &ev) lstColumns->SetItem(pos, COL_STATISTICS, col.GetStatistics()); lstColumns->SetItem(pos, COL_COMMENTS, col.GetComment()); lstColumns->SetItem(pos, COL_TYPEOID, col.GetTypeOid()); + + wxString perColumnListString = wxEmptyString; + + //getting the variable list for each column + wxArrayString perColumnList; + col.GetVariableList(perColumnList); + for(size_t index = 0; index < perColumnList.GetCount(); index++) + { + if (index == 0) + perColumnListString = perColumnList.Item(index); + else + perColumnListString += wxT(",") + perColumnList.Item(index); + } + lstColumns->SetItem(pos, COL_VARIABLE_LIST, perColumnListString); + + //getting the security labels list for each column + if(connection->BackendMinimumVersion(9, 1)) + { + wxString secLabelListString = wxEmptyString; + wxArrayString secLabelList; + col.GetSecLabelList(secLabelList); + for(size_t index = 0; index < secLabelList.GetCount(); index++) + { + if (index == 0) + secLabelListString = secLabelList.Item(index); + else + secLabelListString += wxT(",") + secLabelList.Item(index); + } + lstColumns->SetItem(pos, COL_SECLABEL_LIST, secLabelListString); + } } CheckChange(); @@ -1862,7 +1936,7 @@ void dlgTable::OnRemoveCol(wxCommandEvent &ev) } lstColumns->DeleteCurrentItem(); - + btnChangeCol->Disable(); btnRemoveCol->Disable(); CheckChange(); diff --git a/pgadmin/include/ctl/ctlSeclabelPanel.h b/pgadmin/include/ctl/ctlSeclabelPanel.h index 4bfa0fa..82a293f 100644 --- a/pgadmin/include/ctl/ctlSeclabelPanel.h +++ b/pgadmin/include/ctl/ctlSeclabelPanel.h @@ -42,7 +42,7 @@ public: void SetObject(pgObject *obj); void Disable(); wxString GetSqlForSecLabels(wxString objecttype = wxEmptyString, wxString objectname = wxEmptyString); - + void GetCurrentProviderLabelArray(wxArrayString& secLabels); protected: wxNotebook *nbNotebook; pgConn *connection; @@ -56,7 +56,7 @@ protected: void OnDelSeclabel(wxCommandEvent &ev); void OnProviderChange(wxCommandEvent &ev); void OnSeclabelChange(wxCommandEvent &ev); - + void OnChange(wxCommandEvent &ev); DECLARE_EVENT_TABLE() }; diff --git a/pgadmin/include/ctl/ctlSecurityPanel.h b/pgadmin/include/ctl/ctlSecurityPanel.h index 07f3253..353566b 100644 --- a/pgadmin/include/ctl/ctlSecurityPanel.h +++ b/pgadmin/include/ctl/ctlSecurityPanel.h @@ -51,6 +51,7 @@ public: * Except column level privileges, column will be always an empty string in any case */ wxString GetGrant(const wxString &allPattern, const wxString &grantObject, wxArrayString *currentAcl = 0, wxString column = wxEmptyString); + wxString GetUserPrivileges(); bool DisablePrivilege(const wxString &priv); protected: wxNotebook *nbNotebook; diff --git a/pgadmin/include/dlg/dlgColumn.h b/pgadmin/include/dlg/dlgColumn.h index 6b5bfd8..a849577 100644 --- a/pgadmin/include/dlg/dlgColumn.h +++ b/pgadmin/include/dlg/dlgColumn.h @@ -23,7 +23,7 @@ class dlgColumn : public dlgTypeProperty { public: dlgColumn(pgaFactory *factory, frmMain *frame, pgColumn *column, pgTable *parentNode); - + void SetSecurityPage(const pgColumn* node); void CheckChange(); void SetChangedCol(pgColumn *changedCol); void ApplyChangesToObj(pgColumn *changedCol); @@ -32,6 +32,8 @@ public: pgObject *CreateObject(pgCollection *collection); pgObject *GetObject(); wxString GetDefinition(); + void GetVariableList(wxArrayString& ); + void GetSecLabelList(wxArrayString& ); wxString GetPreviousDefinition() { return previousDefinition; diff --git a/pgadmin/include/dlg/dlgTable.h b/pgadmin/include/dlg/dlgTable.h index f436fda..dccae08 100644 --- a/pgadmin/include/dlg/dlgTable.h +++ b/pgadmin/include/dlg/dlgTable.h @@ -26,7 +26,9 @@ enum COL_STATISTICS, COL_PGCOLUMN, COL_TYPEOID, - COL_CHANGEDCOL + COL_CHANGEDCOL, + COL_VARIABLE_LIST, + COL_SECLABEL_LIST }; enum @@ -55,6 +57,7 @@ public: void CheckChange(); wxString GetSql(); + bool Destroy(); pgObject *CreateObject(pgCollection *collection); pgObject *GetObject(); ~dlgTable();