# HG changeset patch # User Marcin Kuzminski # Date 2017-03-02 17:10:10 # Node ID f2363971b3345d8b8269673e429eb9f83e476c9e # Parent a960166ab163ce91592eca7df9a4398241113db3 user-profile: migrated to pyramid views. diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/_base/__init__.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2017 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import logging +from pylons import tmpl_context as c + +from rhodecode.lib.utils2 import StrictAttributeDict + +log = logging.getLogger(__name__) + + +class TemplateArgs(StrictAttributeDict): + pass + + +class BaseAppView(object): + + def __init__(self, context, request): + self.request = request + self.context = context + self.session = request.session + self._rhodecode_user = request.user + + def _get_local_tmpl_context(self): + return TemplateArgs() + + def _get_template_context(self, tmpl_args): + + for k, v in tmpl_args.items(): + setattr(c, k, v) + + return { + 'defaults': {}, + 'errors': {}, + } + diff --git a/rhodecode/apps/user_profile/__init__.py b/rhodecode/apps/user_profile/__init__.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_profile/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2017 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + + +def includeme(config): + config.add_route( + name='user_profile', + pattern='/_profiles/{username}') + + # Scan module for configuration decorators. + config.scan() diff --git a/rhodecode/apps/user_profile/tests/__init__.py b/rhodecode/apps/user_profile/tests/__init__.py new file mode 100644 diff --git a/rhodecode/apps/user_profile/tests/test_users.py b/rhodecode/apps/user_profile/tests/test_users.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_profile/tests/test_users.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2010-2017 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import pytest + +from rhodecode.model.db import User +from rhodecode.tests import ( + TestController, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, + TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) +from rhodecode.tests.fixture import Fixture +from rhodecode.tests.utils import AssertResponse + +fixture = Fixture() + + +def route_path(name, **kwargs): + return '/_profiles/{username}'.format(**kwargs) + + +class TestUsersController(TestController): + + def test_user_profile(self, user_util): + edit_link_css = '.user-profile .panel-edit' + self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + user = user_util.create_user( + 'test-my-user', password='qweqwe', email='testme@rhodecode.org') + username = user.username + + response = self.app.get(route_path('user_profile', username=username)) + response.mustcontain('testme') + response.mustcontain('testme@rhodecode.org') + assert_response = AssertResponse(response) + assert_response.no_element_exists(edit_link_css) + + # edit should be available to superadmin users + self.logout_user() + self.log_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) + response = self.app.get(route_path('user_profile', username=username)) + assert_response = AssertResponse(response) + assert_response.element_contains(edit_link_css, 'Edit') + + def test_user_profile_not_available(self, user_util): + user = user_util.create_user() + username = user.username + + # not logged in, redirect + self.app.get(route_path('user_profile', username=username), status=302) + + self.log_user() + # after log-in show + self.app.get(route_path('user_profile', username=username), status=200) + + # default user, not allowed to show it + self.app.get( + route_path('user_profile', username=User.DEFAULT_USER), status=404) + + # actual 404 + self.app.get(route_path('user_profile', username='unknown'), status=404) diff --git a/rhodecode/apps/user_profile/views.py b/rhodecode/apps/user_profile/views.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_profile/views.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2017 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import logging + +from pyramid.httpexceptions import HTTPNotFound +from pyramid.view import view_config + +from rhodecode.apps._base import BaseAppView +from rhodecode.lib.auth import LoginRequired, NotAnonymous + +from rhodecode.model.db import User +from rhodecode.model.user import UserModel + +log = logging.getLogger(__name__) + + +class UserProfileView(BaseAppView): + + @LoginRequired() + @NotAnonymous() + @view_config( + route_name='user_profile', request_method='GET', + renderer='rhodecode:templates/users/user.mako') + def login(self): + # register local template context + c = self._get_local_tmpl_context() + c.active = 'user_profile' + + username = self.request.matchdict.get('username') + + c.user = UserModel().get_by_username(username) + if not c.user or c.user.username == User.DEFAULT_USER: + raise HTTPNotFound() + + return self._get_template_context(c) diff --git a/rhodecode/config/middleware.py b/rhodecode/config/middleware.py --- a/rhodecode/config/middleware.py +++ b/rhodecode/config/middleware.py @@ -281,7 +281,11 @@ def includeme(config): config.include('rhodecode.admin') config.include('rhodecode.authentication') config.include('rhodecode.integrations') + + # apps config.include('rhodecode.apps.login') + config.include('rhodecode.apps.user_profile') + config.include('rhodecode.tweens') config.include('rhodecode.api') config.include('rhodecode.svn_support') diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py --- a/rhodecode/config/routing.py +++ b/rhodecode/config/routing.py @@ -92,7 +92,7 @@ class JSRoutesMapper(Mapper): def _extract_route_information(self, route): """ Convert a route into tuple(name, path, args), eg: - ('user_profile', '/profile/%(username)s', ['username']) + ('show_user', '/profile/%(username)s', ['username']) """ routepath = route.routepath def replace(matchobj): @@ -198,10 +198,6 @@ def make_map(config): rmap.connect('user_group_autocomplete_data', '/_user_groups', controller='home', action='user_group_autocomplete_data', jsroute=True) - rmap.connect( - 'user_profile', '/_profiles/{username}', controller='users', - action='user_profile') - # TODO: johbo: Static links, to be replaced by our redirection mechanism rmap.connect('rst_help', 'http://docutils.sourceforge.net/docs/user/rst/quickref.html', diff --git a/rhodecode/controllers/users.py b/rhodecode/controllers/users.py deleted file mode 100644 --- a/rhodecode/controllers/users.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (C) 2010-2017 RhodeCode GmbH -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License, version 3 -# (only), as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# This program is dual-licensed. If you wish to learn more about the -# RhodeCode Enterprise Edition, including its added features, Support services, -# and proprietary license terms, please see https://rhodecode.com/licenses/ - -""" -Users profile controller -""" - -from pylons import tmpl_context as c -from webob.exc import HTTPNotFound - -from rhodecode.lib.auth import LoginRequired, NotAnonymous -from rhodecode.lib.base import BaseController, render -from rhodecode.model.db import User -from rhodecode.model.user import UserModel - - -class UsersController(BaseController): - @LoginRequired() - @NotAnonymous() - def user_profile(self, username): - c.user = UserModel().get_by_username(username) - if not c.user or c.user.username == User.DEFAULT_USER: - raise HTTPNotFound() - - c.active = 'user_profile' - return render('users/user.mako') diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -871,7 +871,7 @@ def link_to_user(author, length=0, **kwa if user: return link_to( escape(display_person), - url('user_profile', username=user.username), + route_path('user_profile', username=user.username), **kwargs) else: return escape(display_person) diff --git a/rhodecode/templates/email_templates/user_registration.mako b/rhodecode/templates/email_templates/user_registration.mako --- a/rhodecode/templates/email_templates/user_registration.mako +++ b/rhodecode/templates/email_templates/user_registration.mako @@ -12,16 +12,16 @@ A new user `${user.username}` has regist - Username: ${user.username} - Full Name: ${user.firstname} ${user.lastname} - Email: ${user.email} -- Profile link: ${h.url('user_profile', username=user.username, qualified=True)} +- Profile link: ${h.route_path('user_profile', username=user.username, qualified=True)} ${self.plaintext_footer()} ## BODY GOES BELOW - + - +

${_('New user %(user)s has registered on %(date)s') % {'user': user.username, 'date': h.format_date(date)}}

${_('New user %(user)s has registered on %(date)s') % {'user': user.username, 'date': h.format_date(date)}}

${_('Username')} ${user.username}
${_('Full Name')}${user.firstname} ${user.lastname}
${_('Email')}${user.email}
${_('Profile')}${h.url('user_profile', username=user.username, qualified=True)}
${_('Profile')}${h.route_path('user_profile', username=user.username, qualified=True)}
\ No newline at end of file diff --git a/rhodecode/templates/users/user.mako b/rhodecode/templates/users/user.mako --- a/rhodecode/templates/users/user.mako +++ b/rhodecode/templates/users/user.mako @@ -12,7 +12,7 @@ <%def name="menu_bar_nav()"> - ${self.menu_items(active='admin')} + ${self.menu_items(active='my_account')} <%def name="main()"> @@ -26,7 +26,7 @@