Changeset - d303aacb3349
[Not reviewed]
default
0 10 0
Marcin Kuzminski - 15 years ago 2010-06-28 13:54:47
marcin@python-works.com
repos crud controllers - change id into repo_name for compatability, added ajax repo perm user function variuos html fixes, permissions forms and managment fixes.
Added permission fetching for each request in AuthUser instance
10 files changed with 118 insertions and 57 deletions:
0 comments (0 inline, 0 general)
pylons_app/config/routing.py
Show inline comments
 
@@ -35,19 +35,22 @@ def make_map(config):
 
             action="new", conditions=dict(method=["GET"]))
 
        m.connect("formatted_new_repo", "/repos/new.{format}",
 
             action="new", conditions=dict(method=["GET"]))
 
        m.connect("/repos/{id:.*}",
 
        m.connect("/repos/{repo_name:.*}",
 
             action="update", conditions=dict(method=["PUT"]))
 
        m.connect("/repos/{id:.*}",
 
        m.connect("/repos/{repo_name:.*}",
 
             action="delete", conditions=dict(method=["DELETE"]))
 
        m.connect("edit_repo", "/repos/{id:.*}/edit",
 
        m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
 
             action="edit", conditions=dict(method=["GET"]))
 
        m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
 
             action="edit", conditions=dict(method=["GET"]))
 
        m.connect("formatted_edit_repo", "/repos/{id:.*}.{format}/edit",
 
             action="edit", conditions=dict(method=["GET"]))
 
        m.connect("repo", "/repos/{id:.*}",
 
        m.connect("repo", "/repos/{repo_name:.*}",
 
             action="show", conditions=dict(method=["GET"]))
 
        m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
 
             action="show", conditions=dict(method=["GET"]))
 
        m.connect("formatted_repo", "/repos/{id:.*}.{format}",
 
             action="show", conditions=dict(method=["GET"]))
 

	
 
        #ajax delete repo perm user
 
        m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
 
             action="delete_perm_user", conditions=dict(method=["DELETE"]))
 
        
 
    map.resource('user', 'users', path_prefix='/_admin')
 
    map.resource('permission', 'permissions', path_prefix='/_admin')
 
    
pylons_app/controllers/repos.py
Show inline comments
 
@@ -34,12 +34,9 @@ from pylons_app.model.repo_model import 
 
from pylons_app.model.hg_model import HgModel
 
from pylons_app.model.forms import RepoForm
 
from pylons_app.model.meta import Session
 
from datetime import datetime
 
import formencode
 
from formencode import htmlfill
 
import logging
 
import os
 
import shutil
 
log = logging.getLogger(__name__)
 

	
 
class ReposController(BaseController):
 
@@ -93,24 +90,24 @@ class ReposController(BaseController):
 

	
 
        return render('admin/repos/repo_add.html')
 

	
 
    def update(self, id):
 
        """PUT /repos/id: Update an existing item"""
 
    def update(self, repo_name):
 
        """PUT /repos/repo_name: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('repo', id=ID),
 
        #    h.form(url('repo', repo_name=ID),
 
        #           method='put')
 
        # url('repo', id=ID)
 
        # url('repo', repo_name=ID)
 
        repo_model = RepoModel()
 
        _form = RepoForm(edit=True)()
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            repo_model.update(id, form_result)
 
            repo_model.update(repo_name, form_result)
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('Repository %s updated succesfully' % id), category='success')
 
            h.flash(_('Repository %s updated succesfully' % repo_name), category='success')
 
                           
 
        except formencode.Invalid as errors:
 
            c.repo_info = repo_model.get(id)
 
            c.repo_info = repo_model.get(repo_name)
 
            c.users_array = repo_model.get_users_js()
 
            errors.value.update({'user':c.repo_info.user.username})
 
            c.form_errors = errors.error_dict
 
@@ -123,59 +120,72 @@ class ReposController(BaseController):
 
                    % form_result['repo_name'], category='error')
 
        return redirect(url('repos'))
 
    
 
    def delete(self, id):
 
        """DELETE /repos/id: Delete an existing item"""
 
    def delete(self, repo_name):
 
        """DELETE /repos/repo_name: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
        # Or using helpers:
 
        #    h.form(url('repo', id=ID),
 
        #    h.form(url('repo', repo_name=ID),
 
        #           method='delete')
 
        # url('repo', id=ID)
 
        # url('repo', repo_name=ID)
 
        
 
        repo_model = RepoModel()
 
        repo = repo_model.get(id)
 
        repo = repo_model.get(repo_name)
 
        if not repo:
 
            h.flash(_('%s repository is not mapped to db perhaps' 
 
                      ' it was moved or renamed  from the filesystem'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % id, category='error')
 
                      ' in order to rescan repositories') % repo_name, category='error')
 
        
 
            return redirect(url('repos'))
 
        try:
 
            repo_model.delete(repo)            
 
            invalidate_cache('cached_repo_list')
 
            h.flash(_('deleted repository %s') % id, category='success')
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 
        except Exception:
 
            h.flash(_('An error occured during deletion of %s') % id,
 
            h.flash(_('An error occured during deletion of %s') % repo_name,
 
                    category='error')
 
        
 
        return redirect(url('repos'))
 
        
 
    def show(self, id, format='html'):
 
        """GET /repos/id: Show a specific item"""
 
        # url('repo', id=ID)
 
    def delete_perm_user(self, repo_name):
 
        """
 
        DELETE an existing repository permission user
 
        @param repo_name:
 
        """
 
        
 
    def edit(self, id, format='html'):
 
        """GET /repos/id/edit: Form to edit an existing item"""
 
        # url('edit_repo', id=ID)
 
        try:
 
            repo_model = RepoModel()
 
            repo_model.delete_perm_user(request.POST, repo_name)            
 
        except Exception as e:
 
            h.flash(_('An error occured during deletion of repository user'),
 
                    category='error')
 
        
 
        
 
    def show(self, repo_name, format='html'):
 
        """GET /repos/repo_name: Show a specific item"""
 
        # url('repo', repo_name=ID)
 
        
 
    def edit(self, repo_name, format='html'):
 
        """GET /repos/repo_name/edit: Form to edit an existing item"""
 
        # url('edit_repo', repo_name=ID)
 
        repo_model = RepoModel()
 
        c.repo_info = repo = repo_model.get(id)
 
        c.repo_info = repo = repo_model.get(repo_name)
 
        if not repo:
 
            h.flash(_('%s repository is not mapped to db perhaps' 
 
                      ' it was created or renamed from the filesystem'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % id, category='error')
 
                      ' in order to rescan repositories') % repo_name, category='error')
 
        
 
            return redirect(url('repos'))        
 
        defaults = c.repo_info.__dict__
 
        defaults.update({'user':c.repo_info.user.username})
 
        
 
        c.users_array = repo_model.get_users_js()
 
        
 
        for p in c.repo_info.repo2perm:
 
            defaults.update({'perm_%s' % p.user.username: 
 
                             p.permission.permission_name})
 
                
 
            
 
        return htmlfill.render(
 
            render('admin/repos/repo_edit.html'),
 
            defaults=defaults,
pylons_app/lib/auth.py
Show inline comments
 
@@ -27,7 +27,7 @@ from functools import wraps
 
from pylons import session, url, app_globals as g
 
from pylons.controllers.util import abort, redirect
 
from pylons_app.model import meta
 
from pylons_app.model.db import User
 
from pylons_app.model.db import User, Repo2Perm
 
from sqlalchemy.exc import OperationalError
 
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
 
import crypt
 
@@ -91,7 +91,18 @@ def set_available_permissions(config):
 
    all_perms = sa.query(Permission).all()
 
    config['pylons.app_globals'].available_permissions = [x.permission_name for x in all_perms]
 

	
 

	
 
def get_user(session):
 
    """
 
    Gets user from session, and wraps permissions into user
 
    @param session:
 
    """
 
    user = session.get('hg_app_user', AuthUser())
 
    if user.is_authenticated:
 
        sa = meta.Session
 
        user.permissions = sa.query(Repo2Perm)\
 
        .filter(Repo2Perm.user_id == user.user_id).all()
 
        
 
    return user
 
        
 
#===============================================================================
 
# DECORATORS
pylons_app/lib/base.py
Show inline comments
 
@@ -5,7 +5,7 @@ Provides the BaseController class for su
 
from pylons import config, tmpl_context as c, request, session
 
from pylons.controllers import WSGIController
 
from pylons.templating import render_mako as render
 
from pylons_app.lib.auth import LoginRequired, AuthUser
 
from pylons_app.lib import auth
 
from pylons_app.lib.utils import get_repo_slug
 
from pylons_app.model import meta
 
from pylons_app.model.hg_model import _get_repos_cached
 
@@ -17,7 +17,7 @@ class BaseController(WSGIController):
 
        c.hg_app_version = __version__
 
        c.repos_prefix = config['hg_app_name']
 
        c.repo_name = get_repo_slug(request)
 
        c.hg_app_user = session.get('hg_app_user', AuthUser())
 
        c.hg_app_user = auth.get_user(session)
 
        c.cached_repo_list = _get_repos_cached()
 
        self.sa = meta.Session
 
    
pylons_app/model/forms.py
Show inline comments
 
@@ -155,7 +155,6 @@ class ValidPerms(formencode.validators.F
 
        perms_new = []
 
        #build a list of permission to update and new permission to create
 
        for k, v in value.items():
 
            print k, v
 
            if k.startswith('perm_'):
 
                if  k.startswith('perm_new_user'):
 
                    new_perm = value.get('perm_new_user', False)
 
@@ -164,9 +163,12 @@ class ValidPerms(formencode.validators.F
 
                        if (new_user, new_perm) not in perms_new:
 
                            perms_new.append((new_user, new_perm))
 
                else:
 
                    perms_update.append((k[5:], v))
 
                #clear from form list
 
                #del value[k]
 
                    usr = k[5:]                    
 
                    if usr == 'default':
 
                        if value['private']:
 
                            #set none for default when updating to private repo
 
                            v = 'repository.none'
 
                    perms_update.append((usr, v))
 
        value['perms_updates'] = perms_update
 
        value['perms_new'] = perms_new
 
        sa = meta.Session
pylons_app/model/repo_model.py
Show inline comments
 
@@ -104,8 +104,10 @@ class RepoModel(object):
 

	
 
            #create default permission
 
            repo2perm = Repo2Perm()
 
            default_perm = 'repository.none' if form_data['private'] \
 
                                                        else 'repository.read'
 
            repo2perm.permission_id = self.sa.query(Permission)\
 
                    .filter(Permission.permission_name == 'repository.read')\
 
                    .filter(Permission.permission_name == default_perm)\
 
                    .one().permission_id
 
                        
 
            repo2perm.repository = repo_name
 
@@ -130,7 +132,16 @@ class RepoModel(object):
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 
       
 
    def delete_perm_user(self, form_data, repo_name):
 
        try:
 
            r2p = self.sa.query(Repo2Perm).filter(Repo2Perm.repository == repo_name)\
 
            .filter(Repo2Perm.user_id == form_data['user_id']).delete()
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 
           
 
    def __create_repo(self, repo_name):        
 
        repo_path = os.path.join(g.base_path, repo_name)
 
        if check_repo(repo_name, g.base_path):
pylons_app/templates/admin/repos/repo_add.html
Show inline comments
 
@@ -30,7 +30,7 @@
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Private')}</td>
 
        		<td>${h.checkbox('private')}</td>
 
        		<td>${h.checkbox('private',value="True")}</td>
 
        		<td>${self.get_form_error('private')}</td>
 
        	</tr>
 
        	<tr>
pylons_app/templates/admin/repos/repo_edit.html
Show inline comments
 
@@ -15,22 +15,22 @@
 
</%def>
 
<%def name="main()">
 
	<div>
 
        <h2>${_('Repositories')} - ${_('edit')}</h2>
 
        ${h.form(url('repo', id=c.repo_info.repo_name),method='put')}
 
        <h2>${_('Repositories')} - ${_('edit')} "${c.repo_name}"</h2>
 
        ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')}
 
        <table>
 
        	<tr>
 
        		<td>${_('Name')}</td>
 
        		<td>${h.text('repo_name')}</td>
 
        		<td>${h.text('repo_name',size="28")}</td>
 
        		<td>${self.get_form_error('repo_name')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Description')}</td>
 
        		<td>${h.textarea('description',cols=23,rows=5)}</td>
 
        		<td>${h.textarea('description',cols=32,rows=5)}</td>
 
        		<td>${self.get_form_error('description')}</td>
 
        	</tr>
 
        	<tr>
 
        		<td>${_('Private')}</td>
 
        		<td>${h.checkbox('private')}</td>
 
        		<td>${h.checkbox('private',value="True")}</td>
 
        		<td>${self.get_form_error('private')}</td>
 
        	</tr>
 
        	<tr>
 
@@ -56,13 +56,37 @@
 
        				</tr>
 
        				
 
        				%for r2p in c.repo_info.repo2perm:
 
	        				<tr>
 
        					%if r2p.user.username =='default' and c.repo_info.private:
 
        						<tr>
 
									<td colspan="4">
 
										<span style="font-size: 0.8em">${_('disabled for private repository')}</span></td>
 
									<td>${r2p.user.username}</td>
 
								</tr>
 
							%else:
 
	        				<tr id=${id(r2p.user.username)}>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.none')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.read')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.write')}</td>
 
	        					<td>${h.radio('perm_%s' % r2p.user.username,'repository.admin')}</td>
 
	        					<td>${r2p.user.username}</td>
 
	        					<td>
 
	        					  %if r2p.user.username !='default':
 
				                  	<span class="delete_icon action_button" onclick="ajaxAction(${r2p.user.user_id},${id(r2p.user.username)})">
 
				                  		<script type="text/javascript">
 
											function ajaxAction(user_id,field_id){
 
												var sUrl = "${h.url('delete_repo_user',repo_name=c.repo_name)}";
 
												var callback = { success:function(o){
 
																YAHOO.util.Dom.get(String(field_id)).innerHTML = '<td colspan="6"></td>';
 
															 }};
 
												var postData = '_method=delete&user_id='+user_id; 
 
												var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); 
 
						                	};
 
										</script>       	
 
				                  	</span>
 
				                  %endif					
 
	        					</td>
 
	        				</tr>
 
	        				%endif
 
						%endfor
 
						<%
 
							if not hasattr(c,'form_errors'):
pylons_app/templates/admin/repos/repos.html
Show inline comments
 
@@ -24,10 +24,10 @@
 
        </tr>
 
	        %for cnt,repo in enumerate(c.repos_list):
 
	 		<tr class="parity${cnt%2}">
 
			    <td>${h.link_to(repo['name'],h.url('edit_repo',id=repo['name']))}</td>
 
			    <td>${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}</td>
 
		        <td>r${repo['rev']}:${repo['tip']}</td>
 
                <td>
 
                  ${h.form(url('repo', id=repo['name']),method='delete')}
 
                  ${h.form(url('repo', repo_name=repo['name']),method='delete')}
 
                  	${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
 
                  ${h.end_form()}
 
     			</td>
pylons_app/templates/base/base.html
Show inline comments
 
@@ -106,7 +106,7 @@ def is_current(selected):
 
	            <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
 
	            <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
 
	            <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
 
				<li>${h.link_to(_('settings'),h.url('edit_repo',id=c.repo_name))}</li>	        
 
				<li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name))}</li>	        
 
	        </ul>
 
		%else:
 
		##Root menu
0 comments (0 inline, 0 general)