##// END OF EJS Templates
user-groups: added info, and new panel to control user group synchronization....
marcink -
r1600:081c7a81 default
parent child Browse files
Show More
@@ -374,6 +374,10 b' def make_map(config):'
374 '/user_groups/{user_group_id}/edit/advanced',
374 '/user_groups/{user_group_id}/edit/advanced',
375 action='edit_advanced', conditions={'method': ['GET']})
375 action='edit_advanced', conditions={'method': ['GET']})
376
376
377 m.connect('edit_user_group_advanced_sync',
378 '/user_groups/{user_group_id}/edit/advanced/sync',
379 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
380
377 m.connect('edit_user_group_members',
381 m.connect('edit_user_group_members',
378 '/user_groups/{user_group_id}/edit/members', jsroute=True,
382 '/user_groups/{user_group_id}/edit/members', jsroute=True,
379 action='user_group_members', conditions={'method': ['GET']})
383 action='user_group_members', conditions={'method': ['GET']})
@@ -117,7 +117,7 b' class UserGroupsController(BaseControlle'
117 def user_group_actions(user_group_id, user_group_name):
117 def user_group_actions(user_group_id, user_group_name):
118 return _render("user_group_actions", user_group_id, user_group_name)
118 return _render("user_group_actions", user_group_id, user_group_name)
119
119
120 ## json generate
120 # json generate
121 group_iter = UserGroupList(UserGroup.query().all(),
121 group_iter = UserGroupList(UserGroup.query().all(),
122 perm_set=['usergroup.admin'])
122 perm_set=['usergroup.admin'])
123
123
@@ -129,6 +129,7 b' class UserGroupsController(BaseControlle'
129 "group_name_raw": user_gr.users_group_name,
129 "group_name_raw": user_gr.users_group_name,
130 "desc": h.escape(user_gr.user_group_description),
130 "desc": h.escape(user_gr.user_group_description),
131 "members": len(user_gr.members),
131 "members": len(user_gr.members),
132 "sync": user_gr.group_data.get('extern_type'),
132 "active": h.bool2icon(user_gr.users_group_active),
133 "active": h.bool2icon(user_gr.users_group_active),
133 "owner": h.escape(h.link_to_user(user_gr.user.username)),
134 "owner": h.escape(h.link_to_user(user_gr.user.username)),
134 "action": user_group_actions(
135 "action": user_group_actions(
@@ -431,7 +432,6 b' class UserGroupsController(BaseControlle'
431 prefix_error=False,
432 prefix_error=False,
432 encoding="UTF-8",
433 encoding="UTF-8",
433 force_defaults=False)
434 force_defaults=False)
434
435 except Exception:
435 except Exception:
436 log.exception("Exception during permissions saving")
436 log.exception("Exception during permissions saving")
437 h.flash(_('An error occurred during permissions saving'),
437 h.flash(_('An error occurred during permissions saving'),
@@ -459,6 +459,36 b' class UserGroupsController(BaseControlle'
459 return render('admin/user_groups/user_group_edit.mako')
459 return render('admin/user_groups/user_group_edit.mako')
460
460
461 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
461 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
462 def edit_advanced_set_synchronization(self, user_group_id):
463 user_group_id = safe_int(user_group_id)
464 user_group = UserGroup.get_or_404(user_group_id)
465
466 existing = user_group.group_data.get('extern_type')
467
468 if existing:
469 new_state = user_group.group_data
470 new_state['extern_type'] = None
471 else:
472 new_state = user_group.group_data
473 new_state['extern_type'] = 'manual'
474 new_state['extern_type_set_by'] = c.rhodecode_user.username
475
476 try:
477 user_group.group_data = new_state
478 Session().add(user_group)
479 Session().commit()
480
481 h.flash(_('User Group synchronization updated successfully'),
482 category='success')
483 except Exception:
484 log.exception("Exception during sync settings saving")
485 h.flash(_('An error occurred during synchronization update'),
486 category='error')
487
488 return redirect(
489 url('edit_user_group_advanced', user_group_id=user_group_id))
490
491 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
462 @XHRRequired()
492 @XHRRequired()
463 @jsonify
493 @jsonify
464 def user_group_members(self, user_group_id):
494 def user_group_members(self, user_group_id):
@@ -501,8 +501,8 b' class UserGroupModel(BaseModel):'
501 if not existing_group:
501 if not existing_group:
502 desc = 'Automatically created from plugin:%s' % extern_type
502 desc = 'Automatically created from plugin:%s' % extern_type
503 # we use first admin account to set the owner of the group
503 # we use first admin account to set the owner of the group
504 existing_group = UserGroupModel().create(gr, desc, owner,
504 existing_group = UserGroupModel().create(
505 group_data={'extern_type': extern_type})
505 gr, desc, owner, group_data={'extern_type': extern_type})
506
506
507 # we can only add users to special groups created via plugins
507 # we can only add users to special groups created via plugins
508 managed = 'extern_type' in existing_group.group_data
508 managed = 'extern_type' in existing_group.group_data
@@ -511,8 +511,7 b' class UserGroupModel(BaseModel):'
511 UserGroupModel().add_user_to_group(existing_group, user)
511 UserGroupModel().add_user_to_group(existing_group, user)
512 else:
512 else:
513 log.debug('Skipping addition to group %s since it is '
513 log.debug('Skipping addition to group %s since it is '
514 'not managed by auth plugins' % gr)
514 'not set to be automatically synchronized' % gr)
515
516
515
517 def change_groups(self, user, groups):
516 def change_groups(self, user, groups):
518 """
517 """
@@ -6,6 +6,8 b''
6 (_('Created on'), h.format_date(c.user_group.created_on), '', '',),
6 (_('Created on'), h.format_date(c.user_group.created_on), '', '',),
7
7
8 (_('Members'), len(c.group_members_obj),'', [x for x in c.group_members_obj]),
8 (_('Members'), len(c.group_members_obj),'', [x for x in c.group_members_obj]),
9 (_('Automatic member sync'), 'Yes' if c.user_group.group_data.get('extern_type') else 'No', '', '',),
10
9 (_('Assigned to repositories'), len(c.group_to_repos),'', [x for x in c.group_to_repos]),
11 (_('Assigned to repositories'), len(c.group_to_repos),'', [x for x in c.group_to_repos]),
10 (_('Assigned to repo groups'), len(c.group_to_repo_groups), '', [x for x in c.group_to_repo_groups]),
12 (_('Assigned to repo groups'), len(c.group_to_repo_groups), '', [x for x in c.group_to_repo_groups]),
11
13
@@ -19,8 +21,55 b''
19 <div class="panel-body">
21 <div class="panel-body">
20 ${base.dt_info_panel(elems)}
22 ${base.dt_info_panel(elems)}
21 </div>
23 </div>
24
22 </div>
25 </div>
23
26
27 <div class="panel panel-default">
28 <div class="panel-heading">
29 <h3 class="panel-title">${_('Group members sync')}</h3>
30 </div>
31 <div class="panel-body">
32 <% sync_type = c.user_group.group_data.get('extern_type') %>
33
34 % if sync_type:
35 <p>
36 ${_('This group is set to be automatically synchronised.')}<br/>
37 ${_('Each member will be added or removed from this groups once they interact with RhodeCode system.')}<br/>
38 ${_('This group synchronization was set by')}: <strong>${sync_type}</strong>
39 </p>
40 % else:
41 <p>
42 ${_('This group is not set to be automatically synchronised')}
43 </p>
44 % endif
45
46 <div>
47 ${h.secure_form(h.url('edit_user_group_advanced_sync', user_group_id=c.user_group.users_group_id), method='post')}
48 <div class="field">
49 <button class="btn btn-default" type="submit">
50 %if sync_type:
51 ${_('Disable synchronization')}
52 %else:
53 ${_('Enable synchronization')}
54 %endif
55 </button>
56 </div>
57 <div class="field">
58 <span class="help-block">
59 %if sync_type:
60 ${_('User group will no longer synchronize membership')}
61 %else:
62 ${_('User group will start to synchronize membership')}
63 %endif
64 </span>
65 </div>
66 ${h.end_form()}
67 </div>
68
69 </div>
70 </div>
71
72
24 <div class="panel panel-danger">
73 <div class="panel panel-danger">
25 <div class="panel-heading">
74 <div class="panel-heading">
26 <h3 class="panel-title">${_('Delete User Group')}</h3>
75 <h3 class="panel-title">${_('Delete User Group')}</h3>
@@ -58,8 +58,10 b''
58 { data: {"_": "members",
58 { data: {"_": "members",
59 "sort": "members",
59 "sort": "members",
60 "type": Number}, title: "${_('Members')}", className: "td-number" },
60 "type": Number}, title: "${_('Members')}", className: "td-number" },
61 { data: {"_": "sync",
62 "sort": "sync"}, title: "${_('Sync')}", className: "td-sync" },
61 { data: {"_": "active",
63 { data: {"_": "active",
62 "sort": "active"}, title: "${_('Active')}", className: "td-active", className: "td-number"},
64 "sort": "active"}, title: "${_('Active')}", className: "td-active" },
63 { data: {"_": "owner",
65 { data: {"_": "owner",
64 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
66 "sort": "owner"}, title: "${_('Owner')}", className: "td-user" },
65 { data: {"_": "action",
67 { data: {"_": "action",
@@ -21,7 +21,7 b''
21 import pytest
21 import pytest
22
22
23 from rhodecode.tests import (
23 from rhodecode.tests import (
24 TestController, url, assert_session_flash, link_to)
24 TestController, url, assert_session_flash, link_to, TEST_USER_ADMIN_LOGIN)
25 from rhodecode.model.db import User, UserGroup
25 from rhodecode.model.db import User, UserGroup
26 from rhodecode.model.meta import Session
26 from rhodecode.model.meta import Session
27 from rhodecode.tests.fixture import Fixture
27 from rhodecode.tests.fixture import Fixture
@@ -56,6 +56,41 b' class TestAdminUsersGroupsController(Tes'
56 response,
56 response,
57 'Created user group %s' % user_group_link)
57 'Created user group %s' % user_group_link)
58
58
59 def test_set_synchronization(self):
60 self.log_user()
61 users_group_name = TEST_USER_GROUP + 'sync'
62 response = self.app.post(url('users_groups'), {
63 'users_group_name': users_group_name,
64 'user_group_description': 'DESC',
65 'active': True,
66 'csrf_token': self.csrf_token})
67
68 group = Session().query(UserGroup).filter(
69 UserGroup.users_group_name == users_group_name).one()
70
71 assert group.group_data.get('extern_type') is None
72
73 # enable
74 self.app.post(
75 url('edit_user_group_advanced_sync', user_group_id=group.users_group_id),
76 params={'csrf_token': self.csrf_token}, status=302)
77
78 group = Session().query(UserGroup).filter(
79 UserGroup.users_group_name == users_group_name).one()
80 assert group.group_data.get('extern_type') == 'manual'
81 assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN
82
83 # disable
84 self.app.post(
85 url('edit_user_group_advanced_sync',
86 user_group_id=group.users_group_id),
87 params={'csrf_token': self.csrf_token}, status=302)
88
89 group = Session().query(UserGroup).filter(
90 UserGroup.users_group_name == users_group_name).one()
91 assert group.group_data.get('extern_type') is None
92 assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN
93
59 def test_delete(self):
94 def test_delete(self):
60 self.log_user()
95 self.log_user()
61 users_group_name = TEST_USER_GROUP + 'another'
96 users_group_name = TEST_USER_GROUP + 'another'
@@ -77,7 +112,7 b' class TestAdminUsersGroupsController(Tes'
77 group = Session().query(UserGroup).filter(
112 group = Session().query(UserGroup).filter(
78 UserGroup.users_group_name == users_group_name).one()
113 UserGroup.users_group_name == users_group_name).one()
79
114
80 response = self.app.post(
115 self.app.post(
81 url('delete_users_group', user_group_id=group.users_group_id),
116 url('delete_users_group', user_group_id=group.users_group_id),
82 params={'_method': 'delete', 'csrf_token': self.csrf_token})
117 params={'_method': 'delete', 'csrf_token': self.csrf_token})
83
118
General Comments 0
You need to be logged in to leave comments. Login now