1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // frmGrantWizard.cpp - Grant Wizard dialogue
9 //
10 //////////////////////////////////////////////////////////////////////////
11
12 // wxWindows headers
13 #include <wx/wx.h>
14 #include <wx/settings.h>
15 #include <wx/xrc/xmlres.h>
16
17
18 // App headers
19 #include "pgAdmin3.h"
20 #include "frm/frmGrantWizard.h"
21 #include "frm/frmMain.h"
22 #include "utils/sysLogger.h"
23 #include "ctl/ctlSecurityPanel.h"
24 #include "schema/pgFunction.h"
25 #include "schema/pgSequence.h"
26 #include "schema/pgTable.h"
27 #include "schema/pgView.h"
28 #include "schema/gpExtTable.h"
29
30 // Icons
31 #include "images/index.pngc"
32
33
34 #define chkList CTRL_CHECKLISTBOX("chkList")
35
36
37
BEGIN_EVENT_TABLE(frmGrantWizard,ExecutionDialog)38 BEGIN_EVENT_TABLE(frmGrantWizard, ExecutionDialog)
39 EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), frmGrantWizard::OnPageSelect)
40 EVT_BUTTON(XRCID("btnChkAll"), frmGrantWizard::OnCheckAll)
41 EVT_BUTTON(XRCID("btnUnchkAll"), frmGrantWizard::OnUncheckAll)
42 EVT_CHECKLISTBOX(XRCID("chkList"), frmGrantWizard::OnChange)
43 END_EVENT_TABLE()
44
45
46 frmGrantWizard::frmGrantWizard(frmMain *form, pgObject *obj) : ExecutionDialog(form, obj)
47 {
48 nbNotebook = 0;
49
50 SetFont(settings->GetSystemFont());
51 LoadResource(form, wxT("frmGrantWizard"));
52 RestorePosition();
53
54 SetTitle(object->GetTranslatedMessage(GRANTWIZARDTITLE));
55
56 // Icon
57 SetIcon(*index_png_ico);
58 nbNotebook = CTRL_NOTEBOOK("nbNotebook");
59 sqlPane = 0;
60
61 Restore();
62 EnableOK(false);
63 }
64
65
~frmGrantWizard()66 frmGrantWizard::~frmGrantWizard()
67 {
68 SavePosition();
69 Abort();
70 }
71
72
GetHelpPage() const73 wxString frmGrantWizard::GetHelpPage() const
74 {
75 wxString page = wxT("pg/sql-grant");
76
77 return page;
78 }
79
OnChange(wxCommandEvent & event)80 void frmGrantWizard::OnChange(wxCommandEvent &event)
81 {
82 sqlPane->SetReadOnly(false);
83 sqlPane->SetText(GetSql());
84 sqlPane->SetReadOnly(true);
85
86 if (sqlPane->GetText().IsEmpty())
87 EnableOK(false);
88 else
89 EnableOK(true);
90 }
91
92
OnUncheckAll(wxCommandEvent & event)93 void frmGrantWizard::OnUncheckAll(wxCommandEvent &event)
94 {
95 unsigned int i;
96 for (i = 0 ; i < chkList->GetCount() ; i++)
97 chkList->Check(i, false);
98
99 OnChange(event);
100 }
101
102
103
OnCheckAll(wxCommandEvent & event)104 void frmGrantWizard::OnCheckAll(wxCommandEvent &event)
105 {
106 unsigned int i;
107 for (i = 0 ; i < chkList->GetCount() ; i++)
108 chkList->Check(i, true);
109
110 OnChange(event);
111 }
112
OnPageSelect(wxNotebookEvent & event)113 void frmGrantWizard::OnPageSelect(wxNotebookEvent &event)
114 {
115 if (nbNotebook && sqlPane && event.GetSelection() == (int)nbNotebook->GetPageCount() - 2)
116 {
117 sqlPane->SetReadOnly(false);
118 sqlPane->SetText(GetSql());
119 sqlPane->SetReadOnly(true);
120 }
121 }
122
123
AddObjects(pgCollection * collection)124 void frmGrantWizard::AddObjects(pgCollection *collection)
125 {
126 bool traverseKids = (!collection->IsCollection() || collection->GetMetaType() == PGM_SCHEMA);
127
128 if (!traverseKids)
129 {
130 pgaFactory *factory = collection->GetFactory();
131 if (!factory->IsCollectionFor(tableFactory) &&
132 !factory->IsCollectionFor(functionFactory) &&
133 !factory->IsCollectionFor(triggerFunctionFactory) &&
134 !factory->IsCollectionFor(procedureFactory) &&
135 !factory->IsCollectionFor(viewFactory) &&
136 !factory->IsCollectionFor(extTableFactory) &&
137 !factory->IsCollectionFor(sequenceFactory))
138 return;
139 }
140
141 wxCookieType cookie;
142 wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(collection->GetId(), cookie);
143
144 while (item)
145 {
146 pgObject *obj = mainForm->GetBrowser()->GetObject(item);
147 if (obj)
148 {
149 if (traverseKids)
150 AddObjects((pgCollection *)obj);
151 else
152 {
153 if (obj->CanEdit())
154 {
155 objectArray.Add(obj);
156 chkList->Append((wxString)wxGetTranslation(obj->GetTypeName()) + wxT(" ") + obj->GetFullIdentifier());
157 }
158 }
159 }
160 item = mainForm->GetBrowser()->GetNextChild(collection->GetId(), cookie);
161 }
162 }
163
Go()164 void frmGrantWizard::Go()
165 {
166 chkList->SetFocus();
167
168 wxString privList = wxT("INSERT,SELECT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER");
169 const char *privChar = "arwdDxt";
170
171 switch (object->GetMetaType())
172 {
173 case PGM_DATABASE:
174 case PGM_SCHEMA:
175 privList.Append(wxT(",EXECUTE,USAGE"));
176 privChar = "arwdDxtXU";
177 break;
178 case PGM_FUNCTION:
179 privList = wxT("EXECUTE");
180 privChar = "X";
181 break;
182 case PGM_SEQUENCE:
183 privList = wxT("SELECT,UPDATE,USAGE");
184 privChar = "rwU";
185 break;
186 case GP_EXTTABLE:
187 privList = wxT("SELECT");
188 privChar = "r";
189 default:
190 break;
191 }
192
193 securityPage = new ctlSecurityPanel(nbNotebook, privList, privChar, mainForm->GetImageList());
194 securityPage->SetConnection(object->GetConnection());
195 this->Connect(EVT_SECURITYPANEL_CHANGE, wxCommandEventHandler(frmGrantWizard::OnChange));
196
197 sqlPane = new ctlSQLBox(nbNotebook, CTL_PROPSQL, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH2);
198 nbNotebook->AddPage(sqlPane, wxT("SQL"));
199
200 txtMessages = new wxTextCtrl(nbNotebook, CTL_MSG, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL);
201 nbNotebook->AddPage(txtMessages, _("Messages"));
202
203 AddObjects((pgCollection *)object);
204
205
206 if (securityPage->cbGroups)
207 {
208 pgSet *set = object->GetConnection()->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname"));
209
210 if (set)
211 {
212 while (!set->Eof())
213 {
214 securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0));
215 set->MoveNext();
216 }
217 delete set;
218 }
219
220 if (settings->GetShowUsersForPrivileges())
221 {
222 set = object->GetConnection()->ExecuteSet(wxT("SELECT usename FROM pg_user ORDER BY usename"));
223
224 if (set)
225 {
226 securityPage->stGroup->SetLabel(_("Group/User"));
227
228 while (!set->Eof())
229 {
230 securityPage->cbGroups->Append(set->GetVal(0));
231 set->MoveNext();
232 }
233 delete set;
234 Layout();
235 }
236 }
237 }
238
239 Layout();
240 Show(true);
241
242 // Work around a weird display bug in wx2.7
243 this->Refresh();
244 }
245
246
GetSql()247 wxString frmGrantWizard::GetSql()
248 {
249 wxString sql;
250
251 unsigned int i;
252 for (i = 0 ; i < chkList->GetCount() ; i++)
253 {
254 if (chkList->IsChecked(i))
255 {
256 wxString tmp;
257
258 pgObject *obj = (pgObject *)objectArray.Item(i);
259
260 switch (obj->GetMetaType())
261 {
262 case PGM_FUNCTION:
263 {
264 if (((pgFunction *)obj)->GetIsProcedure())
265 {
266 tmp = securityPage->GetGrant(wxT("X"), wxT("PROCEDURE ")
267 + obj->GetQuotedFullIdentifier() + wxT("(")
268 + ((pgProcedure *)obj)->GetArgSigList() + wxT(")"));
269 }
270 else
271 {
272 tmp = securityPage->GetGrant(wxT("X"), wxT("FUNCTION ")
273 + obj->GetQuotedFullIdentifier() + wxT("(")
274 + ((pgFunction *)obj)->GetArgSigList() + wxT(")"));
275 }
276 break;
277 }
278 case PGM_VIEW:
279 tmp = securityPage->GetGrant(wxT("arwdxt"), wxT("TABLE ") + obj->GetQuotedFullIdentifier());
280 break;
281 case PGM_SEQUENCE:
282 tmp = securityPage->GetGrant(wxT("rwU"), wxT("SEQUENCE ") + obj->GetQuotedFullIdentifier());
283 break;
284 case GP_EXTTABLE:
285 tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier());
286 default:
287 if (obj->GetTypeName().Upper() == wxT("EXTERNAL TABLE")) // somewhat of a hack
288 {
289 tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier());
290 }
291 else
292 tmp = securityPage->GetGrant(wxT("arwdDxt"), obj->GetTypeName().Upper() + wxT(" ") + obj->GetQuotedFullIdentifier());
293 break;
294 }
295
296 if (!tmp.IsEmpty())
297 sql.Append(tmp);
298 }
299 }
300 return sql;
301 }
302
303
grantWizardFactory(menuFactoryList * list,wxMenu * mnu,ctlMenuToolbar * toolbar)304 grantWizardFactory::grantWizardFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
305 {
306 mnu->Append(id, _("&Grant Wizard..."), _("Grants rights to multiple objects"));
307 }
308
309
StartDialog(frmMain * form,pgObject * obj)310 wxWindow *grantWizardFactory::StartDialog(frmMain *form, pgObject *obj)
311 {
312 frmGrantWizard *frm = new frmGrantWizard(form, obj);
313 frm->Go();
314 return 0;
315 }
316
317
CheckEnable(pgObject * obj)318 bool grantWizardFactory::CheckEnable(pgObject *obj)
319 {
320 if (obj)
321 {
322 switch (obj->GetMetaType())
323 {
324 case PGM_TABLE:
325 case PGM_FUNCTION:
326 case PGM_SEQUENCE:
327 case PGM_VIEW:
328 case GP_EXTTABLE:
329 if (obj->IsCollection() && obj->GetSchema()->GetMetaType() != PGM_CATALOG)
330 return obj->GetSchema()->CanEdit();
331 break;
332
333 case PGM_SCHEMA:
334 return obj->CanEdit();
335 default:
336 break;
337 }
338 }
339 return false;
340 }
341