Show More
@@ -30,13 +30,14 b' import traceback' | |||
|
30 | 30 | import formencode |
|
31 | 31 | |
|
32 | 32 | from formencode import htmlfill |
|
33 | from pylons import request, session, tmpl_context as c, url | |
|
33 | from pylons import request, session, tmpl_context as c, url, config | |
|
34 | 34 | from pylons.controllers.util import abort, redirect |
|
35 | 35 | from pylons.i18n.translation import _ |
|
36 | 36 | |
|
37 |
from rhodecode.lib.exceptions import |
|
|
37 | from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException | |
|
38 | 38 | from rhodecode.lib import helpers as h |
|
39 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator | |
|
39 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \ | |
|
40 | fill_perms | |
|
40 | 41 | from rhodecode.lib.base import BaseController, render |
|
41 | 42 | |
|
42 | 43 | from rhodecode.model.db import User |
@@ -57,7 +58,7 b' class UsersController(BaseController):' | |||
|
57 | 58 | c.admin_user = session.get('admin_user') |
|
58 | 59 | c.admin_username = session.get('admin_username') |
|
59 | 60 | super(UsersController, self).__before__() |
|
60 | ||
|
61 | c.available_permissions = config['available_permissions'] | |
|
61 | 62 | |
|
62 | 63 | def index(self, format='html'): |
|
63 | 64 | """GET /users: All items in the collection""" |
@@ -140,7 +141,7 b' class UsersController(BaseController):' | |||
|
140 | 141 | user_model = UserModel() |
|
141 | 142 | try: |
|
142 | 143 | user_model.delete(id) |
|
143 | h.flash(_('sucessfully deleted user'), category='success') | |
|
144 | h.flash(_('successfully deleted user'), category='success') | |
|
144 | 145 | except (UserOwnsReposException, DefaultUserException), e: |
|
145 | 146 | h.flash(str(e), category='warning') |
|
146 | 147 | except Exception: |
@@ -162,8 +163,11 b' class UsersController(BaseController):' | |||
|
162 | 163 | if c.user.username == 'default': |
|
163 | 164 | h.flash(_("You can't edit this user"), category='warning') |
|
164 | 165 | return redirect(url('users')) |
|
166 | c.user.permissions = {} | |
|
167 | c.granted_permissions = fill_perms(c.user).permissions['global'] | |
|
165 | 168 | |
|
166 | 169 | defaults = c.user.get_dict() |
|
170 | ||
|
167 | 171 | return htmlfill.render( |
|
168 | 172 | render('admin/users/user_edit.html'), |
|
169 | 173 | defaults=defaults, |
@@ -1,8 +1,14 b'' | |||
|
1 | #!/usr/bin/env python | |
|
2 | # encoding: utf-8 | |
|
3 | # authentication and permission libraries | |
|
4 | # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com> | |
|
5 | # | |
|
1 | # -*- coding: utf-8 -*- | |
|
2 | """ | |
|
3 | rhodecode.lib.auth | |
|
4 | ~~~~~~~~~~~~~~~~~~ | |
|
5 | ||
|
6 | authentication and permission libraries | |
|
7 | ||
|
8 | :created_on: Apr 4, 2010 | |
|
9 | :copyright: (c) 2010 by marcink. | |
|
10 | :license: LICENSE_NAME, see LICENSE_FILE for more details. | |
|
11 | """ | |
|
6 | 12 | # This program is free software; you can redistribute it and/or |
|
7 | 13 | # modify it under the terms of the GNU General Public License |
|
8 | 14 | # as published by the Free Software Foundation; version 2 |
@@ -17,26 +23,26 b'' | |||
|
17 | 23 | # along with this program; if not, write to the Free Software |
|
18 | 24 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 | 25 | # MA 02110-1301, USA. |
|
20 | """ | |
|
21 | Created on April 4, 2010 | |
|
22 | 26 | |
|
23 | @author: marcink | |
|
24 | """ | |
|
27 | import bcrypt | |
|
28 | import random | |
|
29 | import logging | |
|
30 | import traceback | |
|
31 | ||
|
32 | from decorator import decorator | |
|
33 | ||
|
25 | 34 | from pylons import config, session, url, request |
|
26 | 35 | from pylons.controllers.util import abort, redirect |
|
27 | from rhodecode.lib.exceptions import * | |
|
36 | ||
|
37 | from rhodecode.lib.exceptions import LdapPasswordError, LdapUsernameError | |
|
28 | 38 | from rhodecode.lib.utils import get_repo_slug |
|
29 | 39 | from rhodecode.lib.auth_ldap import AuthLdap |
|
40 | ||
|
30 | 41 | from rhodecode.model import meta |
|
31 | 42 | from rhodecode.model.user import UserModel |
|
32 | from rhodecode.model.caching_query import FromCache | |
|
33 | 43 | from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \ |
|
34 | 44 | UserToPerm |
|
35 | import bcrypt | |
|
36 | from decorator import decorator | |
|
37 | import logging | |
|
38 | import random | |
|
39 | import traceback | |
|
45 | ||
|
40 | 46 | |
|
41 | 47 | log = logging.getLogger(__name__) |
|
42 | 48 | |
@@ -172,12 +178,13 b' class AuthUser(object):' | |||
|
172 | 178 | return "<AuthUser('id:%s:%s')>" % (self.user_id, self.username) |
|
173 | 179 | |
|
174 | 180 | def set_available_permissions(config): |
|
175 | """ | |
|
176 | This function will propagate pylons globals with all available defined | |
|
181 | """This function will propagate pylons globals with all available defined | |
|
177 | 182 | permission given in db. We don't wannt to check each time from db for new |
|
178 | 183 | permissions since adding a new permission also requires application restart |
|
179 | 184 | ie. to decorate new views with the newly created permission |
|
180 | :param config: | |
|
185 | ||
|
186 | :param config: current pylons config instance | |
|
187 | ||
|
181 | 188 | """ |
|
182 | 189 | log.info('getting information about all available permissions') |
|
183 | 190 | try: |
@@ -195,9 +202,10 b' def set_base_path(config):' | |||
|
195 | 202 | |
|
196 | 203 | |
|
197 | 204 | def fill_perms(user): |
|
198 | """ | |
|
199 | Fills user permission attribute with permissions taken from database | |
|
205 | """Fills user permission attribute with permissions taken from database | |
|
206 | ||
|
200 | 207 | :param user: |
|
208 | ||
|
201 | 209 | """ |
|
202 | 210 | |
|
203 | 211 | sa = meta.Session() |
@@ -117,6 +117,11 b' class User(Base, BaseModel):' | |||
|
117 | 117 | def full_contact(self): |
|
118 | 118 | return '%s %s <%s>' % (self.name, self.lastname, self.email) |
|
119 | 119 | |
|
120 | ||
|
121 | @property | |
|
122 | def is_admin(self): | |
|
123 | return self.admin | |
|
124 | ||
|
120 | 125 | def __repr__(self): |
|
121 | 126 | return "<%s('id:%s:%s')>" % (self.__class__.__name__, |
|
122 | 127 | self.user_id, self.username) |
@@ -113,8 +113,122 b'' | |||
|
113 | 113 | <div class="title"> |
|
114 | 114 | <h5>${_('Permissions')}</h5> |
|
115 | 115 | </div> |
|
116 | <div class="table"> | |
|
117 | Permissions settings goes here ! | |
|
118 | </div> | |
|
116 | <form id="map_form" method="post" action="{%url update_permissions %}"> | |
|
117 | <div class="form"> | |
|
118 | <div class="fields"> | |
|
119 | ||
|
120 | ||
|
121 | ||
|
122 | <table> | |
|
123 | <tr> | |
|
124 | <td class="label">${_('Permissions')}:</td> | |
|
125 | <td> | |
|
126 | <div> | |
|
127 | <div style="float:left"> | |
|
128 | <div class="text">${_('Granted permissions')}</div> | |
|
129 | ${h.select('granted_permissions',[],c.granted_permissions,multiple=True,size=8,style="min-width:210px")} | |
|
130 | </div> | |
|
131 | <div style="float:left;width:20px;padding-top:50px"> | |
|
132 | <img alt="add" id="add_element" | |
|
133 | style="padding:2px;cursor:pointer" | |
|
134 | src="/images/icons/arrow_left.png"> | |
|
135 | <br /> | |
|
136 | <img alt="remove" id="remove_element" | |
|
137 | style="padding:2px;cursor:pointer" | |
|
138 | src="/images/icons/arrow_right.png"> | |
|
139 | </div> | |
|
140 | <div style="float:left"> | |
|
141 | <div class="text">${_('Available permissions')}</div> | |
|
142 | ${h.select('available_permissions',[],c.available_permissions,multiple=True,size=8,style="min-width:210px")} | |
|
143 | </div> | |
|
144 | </div> | |
|
145 | </td> | |
|
146 | </tr> | |
|
147 | ||
|
148 | </table> | |
|
149 | <div class="buttons"> | |
|
150 | ${h.submit('Save','Save',class_="ui-button")} | |
|
151 | </div> | |
|
152 | </div> | |
|
153 | </div> | |
|
154 | </form> | |
|
155 | ||
|
156 | ||
|
157 | <script type="text/javascript"> | |
|
158 | YAHOO.util.Event.onDOMReady(function(){ | |
|
159 | ||
|
160 | var D = YAHOO.util.Dom; | |
|
161 | var E = YAHOO.util.Event; | |
|
162 | ||
|
163 | //temp container for storage. | |
|
164 | var cache = new Array(); | |
|
165 | var c = D.get('id_granted_permissions'); | |
|
166 | ||
|
167 | //get only selected options for further fullfilment | |
|
168 | for(var i = 0;node =c.options[i];i++){ | |
|
169 | if(node.selected){ | |
|
170 | //push selected to my temp storage left overs :) | |
|
171 | cache.push(node); | |
|
172 | } | |
|
173 | } | |
|
174 | ||
|
175 | //clear select | |
|
176 | c.options.length = 0; | |
|
177 | ||
|
178 | //fill it with remembered options | |
|
179 | for(var i = 0;node = cache[i];i++){ | |
|
180 | c.options[i]=new Option(node.text, node.value, false, false); | |
|
181 | } | |
|
182 | ||
|
183 | function target_callback(e){ | |
|
184 | window.location='/admin/t4?g='+e.target.value; | |
|
185 | } | |
|
186 | ||
|
187 | function prompts_action_callback(e){ | |
|
188 | ||
|
189 | var choosen = D.get('id_granted_permissions'); | |
|
190 | var availible = D.get('id_available_permissions'); | |
|
191 | ||
|
192 | if (this.id=='add_element'){ | |
|
193 | for(var i=0; node = availible.options[i];i++){ | |
|
194 | if(node.selected){ | |
|
195 | choosen.appendChild(new Option(node.text, node.value, false, false)); | |
|
196 | } | |
|
197 | } | |
|
198 | } | |
|
199 | else if (this.id=='remove_element'){ | |
|
200 | ||
|
201 | //temp container for storage. | |
|
202 | cache = new Array(); | |
|
203 | ||
|
204 | for(var i = 0;node = choosen.options[i];i++){ | |
|
205 | if(!node.selected){ | |
|
206 | //push left overs :) | |
|
207 | cache.push(node); | |
|
208 | } | |
|
209 | } | |
|
210 | //clear select | |
|
211 | choosen.options.length = 0; | |
|
212 | for(var i = 0;node = cache[i];i++){ | |
|
213 | choosen.options[i]=new Option(node.text, node.value, false, false); | |
|
214 | } | |
|
215 | } | |
|
216 | else{ | |
|
217 | ||
|
218 | } | |
|
219 | } | |
|
220 | ||
|
221 | E.addListener('id_groups','change',target_callback); | |
|
222 | ||
|
223 | E.addListener(['add_element','remove_element'],'click',prompts_action_callback) | |
|
224 | ||
|
225 | E.addListener('map_form','submit',function(){ | |
|
226 | var choosen = D.get('id_granted_permissions'); | |
|
227 | for (var i = 0; i < choosen.options.length; i++) { | |
|
228 | choosen.options[i].selected = 'selected'; | |
|
229 | } | |
|
230 | }) | |
|
231 | }); | |
|
232 | </script> | |
|
119 | 233 | </div> |
|
120 | 234 | </%def> No newline at end of file |
@@ -100,7 +100,7 b' class TestAdminUsersController(TestContr' | |||
|
100 | 100 | new_user = self.sa.query(User).filter(User.username == username).one() |
|
101 | 101 | response = self.app.delete(url('user', id=new_user.user_id)) |
|
102 | 102 | |
|
103 | assert """sucessfully deleted user""" in response.session['flash'][0], 'No info about user deletion' | |
|
103 | assert """successfully deleted user""" in response.session['flash'][0], 'No info about user deletion' | |
|
104 | 104 | |
|
105 | 105 | |
|
106 | 106 | def test_delete_browser_fakeout(self): |
General Comments 0
You need to be logged in to leave comments.
Login now