18 """Specific views for users and groups""" |
18 """Specific views for users and groups""" |
19 |
19 |
20 |
20 |
21 from cubicweb import _ |
21 from cubicweb import _ |
22 |
22 |
23 from hashlib import sha1 # pylint: disable=E0611 |
23 from hashlib import sha1 # pylint: disable=E0611 |
24 |
24 |
25 from six import text_type |
25 from six import text_type |
26 from six.moves import range |
26 from six.moves import range |
27 |
27 |
28 from logilab.mtconverter import xml_escape |
28 from logilab.mtconverter import xml_escape |
29 |
29 |
30 from cubicweb import tags |
30 from cubicweb import tags |
31 from cubicweb.schema import display_name |
|
32 from cubicweb.predicates import one_line_rset, is_instance, match_user_groups |
31 from cubicweb.predicates import one_line_rset, is_instance, match_user_groups |
33 from cubicweb.view import EntityView, StartupView |
32 from cubicweb.view import EntityView, StartupView |
34 from cubicweb.web import action, formwidgets |
33 from cubicweb.web import action, formwidgets |
35 from cubicweb.web.views import uicfg, tabs, tableview, actions, add_etype_button |
34 from cubicweb.web.views import uicfg, tabs, tableview, actions, add_etype_button |
36 |
35 |
37 _pvs = uicfg.primaryview_section |
36 _pvs = uicfg.primaryview_section |
38 _pvs.tag_attribute(('CWUser', 'login'), 'hidden') |
37 _pvs.tag_attribute(('CWUser', 'login'), 'hidden') |
39 |
38 |
40 _affk = uicfg.autoform_field_kwargs |
39 _affk = uicfg.autoform_field_kwargs |
41 _affk.tag_subject_of(('CWUser', 'in_group', 'CWGroup'), |
40 _affk.tag_subject_of(('CWUser', 'in_group', 'CWGroup'), |
42 {'widget': formwidgets.InOutWidget}) |
41 {'widget': formwidgets.InOutWidget}) |
|
42 |
43 |
43 |
44 class UserPreferencesEntityAction(action.Action): |
44 class UserPreferencesEntityAction(action.Action): |
45 __regid__ = 'prefs' |
45 __regid__ = 'prefs' |
46 __select__ = (one_line_rset() & is_instance('CWUser') & |
46 __select__ = (one_line_rset() & is_instance('CWUser') & |
47 match_user_groups('owners', 'managers')) |
47 match_user_groups('owners', 'managers')) |
64 |
64 |
65 def call(self): |
65 def call(self): |
66 self.w(u'''<?xml version="1.0" encoding="%s"?> |
66 self.w(u'''<?xml version="1.0" encoding="%s"?> |
67 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
67 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
68 xmlns:rdfs="http://www.w3org/2000/01/rdf-schema#" |
68 xmlns:rdfs="http://www.w3org/2000/01/rdf-schema#" |
69 xmlns:foaf="http://xmlns.com/foaf/0.1/"> '''% self._cw.encoding) |
69 xmlns:foaf="http://xmlns.com/foaf/0.1/"> ''' % self._cw.encoding) |
70 for i in range(self.cw_rset.rowcount): |
70 for i in range(self.cw_rset.rowcount): |
71 self.cell_call(i, 0) |
71 self.cell_call(i, 0) |
72 self.w(u'</rdf:RDF>\n') |
72 self.w(u'</rdf:RDF>\n') |
73 |
73 |
74 def entity_call(self, entity, **kwargs): |
74 def entity_call(self, entity, **kwargs): |
119 'Any U, FN, LN, CD, LL ORDERBY L WHERE U in_group G, ' |
119 'Any U, FN, LN, CD, LL ORDERBY L WHERE U in_group G, ' |
120 'U login L, U firstname FN, U surname LN, U creation_date CD, ' |
120 'U login L, U firstname FN, U surname LN, U creation_date CD, ' |
121 'U last_login_time LL, G eid %(x)s', {'x': entity.eid}) |
121 'U last_login_time LL, G eid %(x)s', {'x': entity.eid}) |
122 self.wview('cwgroup.users', rset, 'null') |
122 self.wview('cwgroup.users', rset, 'null') |
123 |
123 |
|
124 |
124 class CWGroupUsersTable(tableview.RsetTableView): |
125 class CWGroupUsersTable(tableview.RsetTableView): |
125 __regid__ = 'cwgroup.users' |
126 __regid__ = 'cwgroup.users' |
126 __select__ = is_instance('CWUser') |
127 __select__ = is_instance('CWUser') |
127 headers = (_(u'user'), _(u'first name'), _(u'last name'), |
128 headers = (_(u'user'), _(u'first name'), _(u'last name'), |
128 _(u'creation date'), _(u'last login time')) |
129 _(u'creation date'), _(u'last login time')) |
133 class CWGroupPermTab(EntityView): |
134 class CWGroupPermTab(EntityView): |
134 __regid__ = 'cwgroup-permissions' |
135 __regid__ = 'cwgroup-permissions' |
135 __select__ = is_instance('CWGroup') |
136 __select__ = is_instance('CWGroup') |
136 |
137 |
137 def entity_call(self, entity): |
138 def entity_call(self, entity): |
138 self._cw.add_css(('cubicweb.schema.css','cubicweb.acl.css')) |
139 self._cw.add_css(('cubicweb.schema.css', 'cubicweb.acl.css')) |
139 access_types = ('read', 'delete', 'add', 'update') |
|
140 w = self.w |
|
141 objtype_access = {'CWEType': ('read', 'delete', 'add', 'update'), |
140 objtype_access = {'CWEType': ('read', 'delete', 'add', 'update'), |
142 'CWRelation': ('add', 'delete')} |
141 'CWRelation': ('add', 'delete')} |
143 rql_cwetype = 'DISTINCT Any X WHERE X %s_permission CWG, X is CWEType, ' \ |
142 rql_cwetype = 'DISTINCT Any X WHERE X %s_permission CWG, X is CWEType, ' \ |
144 'CWG eid %%(e)s' |
143 'CWG eid %%(e)s' |
145 rql_cwrelation = 'DISTINCT Any RT WHERE X %s_permission CWG, X is CWRelation, ' \ |
144 rql_cwrelation = 'DISTINCT Any RT WHERE X %s_permission CWG, X is CWRelation, ' \ |
168 |
167 |
169 |
168 |
170 # user / groups management views ############################################### |
169 # user / groups management views ############################################### |
171 |
170 |
172 class ManageUsersAction(actions.ManagersAction): |
171 class ManageUsersAction(actions.ManagersAction): |
173 __regid__ = 'cwuser' # see rewrite rule /cwuser |
172 __regid__ = 'cwuser' # see rewrite rule /cwuser |
174 title = _('users and groups') |
173 title = _('users and groups') |
175 category = 'manage' |
174 category = 'manage' |
176 |
175 |
177 |
176 |
178 class UsersAndGroupsManagementView(tabs.TabsMixin, StartupView): |
177 class UsersAndGroupsManagementView(tabs.TabsMixin, StartupView): |
179 __regid__ = 'cw.users-and-groups-management' |
178 __regid__ = 'cw.users-and-groups-management' |
180 __select__ = StartupView.__select__ & match_user_groups('managers') |
179 __select__ = StartupView.__select__ & match_user_groups('managers') |
181 title = _('Users and groups management') |
180 title = _('Users and groups management') |
182 tabs = [_('cw.users-management'), _('cw.groups-management'),] |
181 tabs = [_('cw.users-management'), _('cw.groups-management')] |
183 default_tab = 'cw.users-management' |
182 default_tab = 'cw.users-management' |
184 |
183 |
185 def call(self, **kwargs): |
184 def call(self, **kwargs): |
186 """The default view representing the instance's management""" |
185 """The default view representing the instance's management""" |
187 self.w(u'<h1>%s</h1>' % self._cw._(self.title)) |
186 self.w(u'<h1>%s</h1>' % self._cw._(self.title)) |
189 |
188 |
190 |
189 |
191 class CWUserManagementView(StartupView): |
190 class CWUserManagementView(StartupView): |
192 __regid__ = 'cw.users-management' |
191 __regid__ = 'cw.users-management' |
193 __select__ = StartupView.__select__ & match_user_groups('managers') |
192 __select__ = StartupView.__select__ & match_user_groups('managers') |
194 cache_max_age = 0 # disable caching |
193 cache_max_age = 0 # disable caching |
195 # XXX one could wish to display for instance only user's firstname/surname |
194 # XXX one could wish to display for instance only user's firstname/surname |
196 # for non managers but filtering out NULL caused crash with an ldapuser |
195 # for non managers but filtering out NULL caused crash with an ldapuser |
197 # source. The ldapuser source has been dropped and this code can be updated. |
196 # source. The ldapuser source has been dropped and this code can be updated. |
198 rql = ('Any U,US,F,S,U,UAA,UDS, L,UAA,USN,UDSN ORDERBY L WHERE U is CWUser, ' |
197 rql = ('Any U,US,F,S,U,UAA,UDS, L,UAA,USN,UDSN ORDERBY L WHERE U is CWUser, ' |
199 'U login L, U firstname F, U surname S, ' |
198 'U login L, U firstname F, U surname S, ' |
215 layout_args = {'display_filter': 'top'} |
214 layout_args = {'display_filter': 'top'} |
216 finalvid = 'editable-final' |
215 finalvid = 'editable-final' |
217 |
216 |
218 column_renderers = { |
217 column_renderers = { |
219 'user': tableview.EntityTableColRenderer( |
218 'user': tableview.EntityTableColRenderer( |
220 renderfunc=lambda w,x: w(tags.a(x.login, href=x.absolute_url())), |
219 renderfunc=lambda w, x: w(tags.a(x.login, href=x.absolute_url())), |
221 sortfunc=lambda x: x.login), |
220 sortfunc=lambda x: x.login), |
222 'in_state': tableview.EntityTableColRenderer( |
221 'in_state': tableview.EntityTableColRenderer( |
223 renderfunc=lambda w,x: w(x.cw_adapt_to('IWorkflowable').printable_state), |
222 renderfunc=lambda w, x: w(x.cw_adapt_to('IWorkflowable').printable_state), |
224 sortfunc=lambda x: x.cw_adapt_to('IWorkflowable').printable_state), |
223 sortfunc=lambda x: x.cw_adapt_to('IWorkflowable').printable_state), |
225 'in_group': tableview.EntityTableColRenderer( |
224 'in_group': tableview.EntityTableColRenderer( |
226 renderfunc=lambda w,x: x.view('reledit', rtype='in_group', role='subject', w=w)), |
225 renderfunc=lambda w, x: x.view('reledit', rtype='in_group', role='subject', w=w)), |
227 'primary_email': tableview.RelatedEntityColRenderer( |
226 'primary_email': tableview.RelatedEntityColRenderer( |
228 getrelated=lambda x:x.primary_email and x.primary_email[0] or None), |
227 getrelated=lambda x: x.primary_email and x.primary_email[0] or None), |
229 'cw_source': tableview.RelatedEntityColRenderer( |
228 'cw_source': tableview.RelatedEntityColRenderer( |
230 getrelated=lambda x: x.cw_source[0]), |
229 getrelated=lambda x: x.cw_source[0]), |
231 } |
230 } |
232 |
231 |
233 |
232 |
234 class CWGroupsManagementView(StartupView): |
233 class CWGroupsManagementView(StartupView): |
235 __regid__ = 'cw.groups-management' |
234 __regid__ = 'cw.groups-management' |
236 __select__ = StartupView.__select__ & match_user_groups('managers') |
235 __select__ = StartupView.__select__ & match_user_groups('managers') |
237 cache_max_age = 0 # disable caching |
236 cache_max_age = 0 # disable caching |
238 rql = ('Any G,GN ORDERBY GN WHERE G is CWGroup, G name GN, NOT G name "owners"') |
237 rql = ('Any G,GN ORDERBY GN WHERE G is CWGroup, G name GN, NOT G name "owners"') |
239 |
238 |
240 def call(self, **kwargs): |
239 def call(self, **kwargs): |
241 self.w(add_etype_button(self._cw, 'CWGroup')) |
240 self.w(add_etype_button(self._cw, 'CWGroup')) |
242 self.w(u'<div class="clear"></div>') |
241 self.w(u'<div class="clear"></div>') |
251 |
250 |
252 column_renderers = { |
251 column_renderers = { |
253 'group': tableview.MainEntityColRenderer(), |
252 'group': tableview.MainEntityColRenderer(), |
254 'nb_users': tableview.EntityTableColRenderer( |
253 'nb_users': tableview.EntityTableColRenderer( |
255 header=_('num. users'), |
254 header=_('num. users'), |
256 renderfunc=lambda w,x: w(text_type(x.num_users())), |
255 renderfunc=lambda w, x: w(text_type(x.num_users())), |
257 sortfunc=lambda x: x.num_users()), |
256 sortfunc=lambda x: x.num_users()), |
258 } |
257 } |