Add dynamic site configuration to Review Board
Updated 4 months ago
| Christian Hammond | Reviewers | ||
| trunk | reviewboard | ||
| None | Review Board SVN | ||
Up until now users have had to edit settings_local.py to customize their Review Board install. While we documented many of the options, it was still a pain for users as they'd have to log in and edit the file and then restart the server. With the new djblets.siteconfig app, we can now move in a more modern direction for customization of Review Board. Aside from a few basic essential settings in settings_local.py (such as database configuration) the admin UI will now be the place to go to customize Review Board. A migration script is provided to automatically migrate all settings into the new siteconfig database entry. The next time users run ./manage.py syncdb, the script will detect that the settings need to be migrated and handle it all. Everything we care about should be preserved, including authentication information.
I've tested this with brand new installs and with a few different migrated databases. I haven't hit any problems yet but I haven't actually tested the resulting settings for authentication. Users can specify NIS or LDAP servers and I know we save the information but before this goes in, I'll be testing on an actual install.
Diff revision 3 (Latest)
- /trunk/reviewboard/manage.py: 6 changes [ 1 2 3 4 5 6 ]
- /trunk/reviewboard/settings.py: 6 changes [ 1 2 3 4 5 6 ]
- /trunk/reviewboard/settings_local.py.tmpl: 2 changes [ 1 2 ]
- /trunk/reviewboard/urls.py: 5 changes [ 1 2 3 4 5 ]
- /trunk/reviewboard/accounts/backends.py: 1 change [ 1 ]
- /trunk/reviewboard/accounts/decorators.py: 4 changes [ 1 2 3 4 ]
- /trunk/reviewboard/accounts/forms.py: 4 changes [ 1 2 3 4 ]
- /trunk/reviewboard/accounts/urls.py: 1 change [ new content ]
- /trunk/reviewboard/accounts/views.py: 6 changes [ 1 2 3 4 5 6 ]
- /trunk/reviewboard/admin/checks.py: 2 changes [ 1 2 ]
- /trunk/reviewboard/admin/forms.py: 1 change [ new content ]
- /trunk/reviewboard/admin/siteconfig.py: 1 change [ new content ]
- /trunk/reviewboard/admin/urls.py: 5 changes [ 1 2 3 4 5 ]
- /trunk/reviewboard/admin/management/__init__.py: 5 changes [ 1 2 3 4 5 ]
- /trunk/reviewboard/admin/management/evolutions.py: 1 change [ new content ]
- /trunk/reviewboard/admin/management/sites.py: 1 change [ new content ]
- /trunk/reviewboard/contrib/tools/post-review: 3 changes [ 1 2 3 ]
- /trunk/reviewboard/diffviewer/diffutils.py: 12 changes [ 1 2 3 4 5 6 7 8 9 10 11 12 ]
- /trunk/reviewboard/diffviewer/tests.py: 4 changes [ 1 2 3 4 ]
- /trunk/reviewboard/diffviewer/views.py: 6 changes [ 1 2 3 4 5 6 ]
| /trunk/reviewboard/manage.py | |||
|---|---|---|---|
| Revision 1421 | New Change | ||
| 1 |
|
1 |
|
| 2 | 2 | ||
| 3 | import imp |
3 | import imp |
| 4 | import sys |
4 | import sys |
| 5 | import os |
5 | import os |
| 6 | from os.path import abspath, dirname |
6 | from os.path import abspath, dirname |
| 7 | 7 | ||
| 8 | from django.core.management import execute_manager |
8 | from django.core.management import execute_manager, setup_environ |
| 9 | from django.template.defaultfilters import striptags |
||
| 9 | 10 | ||
| 10 | # Add the parent directory of 'manage.py' to the python path, so manage.py can |
11 | # Add the parent directory of 'manage.py' to the python path, so manage.py can |
| 11 | # be run from any directory. From http://www.djangosnippets.org/snippets/281/ |
12 | # be run from any directory. From http://www.djangosnippets.org/snippets/281/ |
| 12 | sys.path.insert(0, dirname(dirname(abspath(__file__)))) |
13 | sys.path.insert(0, dirname(dirname(abspath(__file__)))) |
| 13 | 14 | ||
| 14 | try: |
15 | try: |
| 15 | import settings # Assumed to be in the same directory. |
16 | import settings # Assumed to be in the same directory. |
| 16 | except ImportError: |
17 | except ImportError: |
| 17 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) |
18 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) |
| 18 | sys.exit(1) |
19 | sys.exit(1) |
| 19 | 20 | ||
| 21 | from reviewboard.admin import checks |
||
| 22 | |||
| 20 | 23 | ||
| 21 | warnings_found = 0 |
24 | warnings_found = 0 |
| 22 | def check_dependencies(): |
25 | def check_dependencies(): |
| 23 | from settings import dependency_error |
26 | from settings import dependency_error |
| 24 | 27 | ||
| 28 | # Some of our checks require access to django.conf.settings, so |
||
| 29 | # tell Django about our settings. |
||
| 30 | setup_environ(settings) |
||
| 31 | |||
| 25 | # Python 2.4 |
32 | # Python 2.4 |
| 26 | if sys.version_info[0] < 2 or \ |
33 | if sys.version_info[0] < 2 or \ |
| 27 | (sys.version_info[0] == 2 and sys.version_info[1] < 4): |
34 | (sys.version_info[0] == 2 and sys.version_info[1] < 4): |
| 28 | dependency_error('Python 2.4 or newer is required.') |
35 | dependency_error('Python 2.4 or newer is required.') |
| 29 | 36 | ||
| ... | 18 lines hidden [Expand] | ||
| 48 | except ImportError: |
55 | except ImportError: |
| 49 | dependency_error('The Python Imaging Library (PIL) is required.') |
56 | dependency_error('The Python Imaging Library (PIL) is required.') |
| 50 | 57 | ||
| 51 | import subprocess |
58 | import subprocess |
| 52 | 59 | ||
| 53 | # pygments |
||
| 54 | if settings.DIFF_SYNTAX_HIGHLIGHTING: |
||
| 55 | try: |
||
| 56 | import pygments |
||
| 57 | version = pygments.__version__.split(".") |
||
| 58 | if version[0] == 0 and version[1] < 9: |
||
| 59 | dependency_error('Pygments is installed, but is an old version. ' |
||
| 60 | 'Versions prior to 0.9 are known to have ' |
||
| 61 | 'serious problems.') |
||
| 62 | except ImportError: |
||
| 63 | dependency_error('The Pygments library is required when ' + |
||
| 64 | 'DIFF_SYNTAX_HIGHLIGHTING is enabled.') |
||
| 65 | |||
| 66 | # PyLucene |
||
| 67 | if settings.ENABLE_SEARCH: |
||
| 68 | try: |
||
| 69 | import lucene |
||
| 70 | except ImportError: |
||
| 71 | dependency_error('PyLucene (with JCC) is required when ' |
||
| 72 | 'ENABLE_SEARCH is set.') |
||
| 73 | |||
| 74 | # The following checks are non-fatal warnings, since these dependencies are |
60 | # The following checks are non-fatal warnings, since these dependencies are |
| 75 | # merely recommended, not required. |
61 | # merely recommended, not required. |
| 76 | def dependency_warning(string): |
62 | def dependency_warning(string): |
| 77 | sys.stderr.write('Warning: %s\n' % string) |
63 | sys.stderr.write('Warning: %s\n' % string) |
| 78 | global warnings_found |
64 | global warnings_found |
| ... | 16 lines hidden [Expand] | ||
| 95 | try: |
81 | try: |
| 96 | imp.find_module('mercurial') |
82 | imp.find_module('mercurial') |
| 97 | except ImportError: |
83 | except ImportError: |
| 98 | dependency_warning('hg not found. Mercurial integration will not work.') |
84 | dependency_warning('hg not found. Mercurial integration will not work.') |
| 99 | 85 | ||
| 86 | for check_func in (checks.get_can_enable_search, |
||
| 87 | checks.get_can_enable_syntax_highlighting): |
||
| 88 | success, reason = check_func() |
||
| 89 | |||
| 90 | if not success: |
||
| 91 | dependency_warning(striptags(reason)) |
||
| 92 | |||
| 100 | found = False |
93 | found = False |
| 101 | for dir in os.environ['PATH'].split(os.environ.get('IFS', ':')): |
94 | for dir in os.environ['PATH'].split(os.environ.get('IFS', ':')): |
| 102 | if os.path.exists(os.path.join(dir, 'git')): |
95 | if os.path.exists(os.path.join(dir, 'git')): |
| 103 | found = True |
96 | found = True |
| 104 | break |
97 | break |
| ... | 24 lines hidden [Expand] | ||
| /trunk/reviewboard/settings.py | |||
|---|---|---|---|
| Revision 1421 | New Change | ||
| ... | 47 lines hidden [Expand] | ||
| 48 | 'django.core.context_processors.auth', |
48 | 'django.core.context_processors.auth', |
| 49 | 'django.core.context_processors.debug', |
49 | 'django.core.context_processors.debug', |
| 50 | 'django.core.context_processors.i18n', |
50 | 'django.core.context_processors.i18n', |
| 51 | 'django.core.context_processors.media', |
51 | 'django.core.context_processors.media', |
| 52 | 'django.core.context_processors.request', |
52 | 'django.core.context_processors.request', |
| 53 | 'djblets.siteconfig.context_processors.siteconfig', |
||
| 53 | 'djblets.util.context_processors.settingsVars', |
54 | 'djblets.util.context_processors.settingsVars', |
| 54 | 'djblets.util.context_processors.siteRoot', |
55 | 'djblets.util.context_processors.siteRoot', |
| 55 | ) |
56 | ) |
| 56 | 57 | ||
| 57 | SITE_ROOT_URLCONF = 'reviewboard.urls' |
58 | SITE_ROOT_URLCONF = 'reviewboard.urls' |
| ... | 19 lines hidden [Expand] | ||
| 77 | 'django.contrib.markup', |
78 | 'django.contrib.markup', |
| 78 | 'django.contrib.sites', |
79 | 'django.contrib.sites', |
| 79 | 'django.contrib.sessions', |
80 | 'django.contrib.sessions', |
| 80 | 'djblets.datagrid', |
81 | 'djblets.datagrid', |
| 81 | 'djblets.feedview', |
82 | 'djblets.feedview', |
| 83 | 'djblets.siteconfig', |
||
| 82 | 'djblets.util', |
84 | 'djblets.util', |
| 83 | 'djblets.webapi', |
85 | 'djblets.webapi', |
| 84 | 'reviewboard.accounts', |
86 | 'reviewboard.accounts', |
| 85 | 'reviewboard.admin', |
87 | 'reviewboard.admin', |
| 86 | 'reviewboard.diffviewer', |
88 | 'reviewboard.diffviewer', |
| ... | 8 lines hidden [Expand] | ||
| 95 | WEB_API_ENCODERS = ( |
97 | WEB_API_ENCODERS = ( |
| 96 | 'djblets.webapi.core.BasicAPIEncoder', |
98 | 'djblets.webapi.core.BasicAPIEncoder', |
| 97 | 'reviewboard.webapi.json.ReviewBoardAPIEncoder', |
99 | 'reviewboard.webapi.json.ReviewBoardAPIEncoder', |
| 98 | ) |
100 | ) |
| 99 | 101 | ||
| 100 | # Whether to use django's built-in system for users. This turns on certain |
||
| 101 | # features like the registration page and profile editing. If you're tying |
||
| 102 | # reviewboard in to an existing authentication environment (such as NIS), |
||
| 103 | # this data will come in from outside. |
||
| 104 | BUILTIN_AUTH = True |
||
| 105 | AUTH_PROFILE_MODULE = "accounts.Profile" |
102 | AUTH_PROFILE_MODULE = "accounts.Profile" |
| 106 | 103 | ||
| 107 | # Default repository path to use for the source code. |
||
| 108 | DEFAULT_REPOSITORY_PATH = None |
||
| 109 | |||
| 110 | # Default expiration time for the cache. Note that this has no effect unless |
104 | # Default expiration time for the cache. Note that this has no effect unless |
| 111 | # CACHE_BACKEND is specified in settings_local.py |
105 | # CACHE_BACKEND is specified in settings_local.py |
| 112 | CACHE_EXPIRATION_TIME = 60 * 60 * 24 * 30 # 1 month |
106 | CACHE_EXPIRATION_TIME = 60 * 60 * 24 * 30 # 1 month |
| 113 | 107 | ||
| 114 | # Custom test runner, which uses nose to find tests and execute them. This |
108 | # Custom test runner, which uses nose to find tests and execute them. This |
| 115 | # gives us a somewhat more comprehensive test execution than django's built-in |
109 | # gives us a somewhat more comprehensive test execution than django's built-in |
| 116 | # runner, as well as some special features like a code coverage report. |
110 | # runner, as well as some special features like a code coverage report. |
| 117 | TEST_RUNNER = 'reviewboard.test.runner' |
111 | TEST_RUNNER = 'reviewboard.test.runner' |
| 118 | 112 | ||
| 119 | # Default diff settings |
||
| 120 | DIFF_CONTEXT_NUM_LINES = 5 |
||
| 121 | DIFF_CONTEXT_COLLAPSE_THRESHOLD = 2 * DIFF_CONTEXT_NUM_LINES + 3 |
||
| 122 | |||
| 123 | # List of file patterns that will show whitespace-only changes. The |
||
| 124 | # default behavior for diffs is to hide lines showing only leading |
||
| 125 | # whitespace changes. |
||
| 126 | # |
||
| 127 | # For example: |
||
| 128 | # |
||
| 129 | # DIFF_INCLUDE_SPACE_PATTERNS = ["*.py", "*.txt"] |
||
| 130 | # |
||
| 131 | DIFF_INCLUDE_SPACE_PATTERNS = [] |
||
| 132 | |||
| 133 | # When enabled, this will send e-mails for all review requests and comments |
||
| 134 | # out to the e-mail addresses defined for the group. |
||
| 135 | SEND_REVIEW_MAIL = False |
||
| 136 | |||
| 137 | # Enable syntax highlighting in the diff viewer |
||
| 138 | DIFF_SYNTAX_HIGHLIGHTING = False |
||
| 139 | |||
| 140 | # Access method used for the site, used in e-mails. Override this in |
||
| 141 | # settings_local.py if you choose to use https instead of http. |
||
| 142 | DOMAIN_METHOD = "http" |
||
| 143 | |||
| 144 | # Require a login for accessing any part of the site. If False, review |
||
| 145 | # requests, diffs, lists of review requests, etc. will be accessible without |
||
| 146 | # a login. |
||
| 147 | REQUIRE_SITEWIDE_LOGIN = False |
||
| 148 | |||
| 149 | # Enable search. See the comment in settings_local.py for more information on |
||
| 150 | # what's required to get this working. |
||
| 151 | ENABLE_SEARCH = False |
||
| 152 | SEARCH_INDEX = os.path.join(REVIEWBOARD_ROOT, 'search-index') |
||
| 153 | |||
| 154 | # The number of files to display per page in the diff viewer |
||
| 155 | DIFFVIEWER_PAGINATE_BY = 20 |
||
| 156 | |||
| 157 | # The number of extra files required before adding another page |
||
| 158 | DIFFVIEWER_PAGINATE_ORPHANS = 10 |
||
| 159 | |||
| 160 | # Dependency checker functionality. Gives our users nice errors when they start |
113 | # Dependency checker functionality. Gives our users nice errors when they start |
| 161 | # out, instead of encountering them later on. Most of the magic for this |
114 | # out, instead of encountering them later on. Most of the magic for this |
| 162 | # happens in manage.py, not here. |
115 | # happens in manage.py, not here. |
| 163 | install_help = ''' |
116 | install_help = ''' |
| 164 | Please see http://code.google.com/p/reviewboard/wiki/GettingStarted |
117 | Please see http://code.google.com/p/reviewboard/wiki/GettingStarted |
| ... | 27 lines hidden [Expand] | ||
| 192 | # Base these on the user's SITE_ROOT. |
145 | # Base these on the user's SITE_ROOT. |
| 193 | LOGIN_URL = SITE_ROOT + 'account/login/' |
146 | LOGIN_URL = SITE_ROOT + 'account/login/' |
| 194 | ADMIN_MEDIA_PREFIX = MEDIA_URL + 'admin/' |
147 | ADMIN_MEDIA_PREFIX = MEDIA_URL + 'admin/' |
| 195 | 148 | ||
| 196 | # Cookie settings |
149 | # Cookie settings |
| 150 | LANGUAGE_COOKIE_NAME = "rblanguage" |
||
| 197 | SESSION_COOKIE_NAME = "rbsessionid" |
151 | SESSION_COOKIE_NAME = "rbsessionid" |
| 198 | SESSION_COOKIE_AGE = 365 * 24 * 24 * 60 # 1 year |
152 | SESSION_COOKIE_AGE = 365 * 24 * 24 * 60 # 1 year |
| 199 | SESSION_COOKIE_PATH = SITE_ROOT |
153 | SESSION_COOKIE_PATH = SITE_ROOT |
| /trunk/reviewboard/settings_local.py.tmpl | |||
|---|---|---|---|
| Revision 1421 | New Change | ||
| ... | 10 lines hidden [Expand] | ||
| 11 | 11 | ||
| 12 | # Cache backend. Unset this to turn off caching completely. As with most |
12 | # Cache backend. Unset this to turn off caching completely. As with most |
| 13 | # django installations, the best option is probably to use memcached. |
13 | # django installations, the best option is probably to use memcached. |
| 14 | CACHE_BACKEND = 'locmem:///' |
14 | CACHE_BACKEND = 'locmem:///' |
| 15 | 15 | ||
| 16 | # Whether to send e-mail for review requests. |
||
| 17 | SEND_REVIEW_MAIL = False |
||
| 18 | |||
| 19 | # Local time zone for this installation. All choices can be found here: |
16 | # Local time zone for this installation. All choices can be found here: |
| 20 | # http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE |
17 | # http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE |
| 21 | TIME_ZONE = 'US/Pacific' |
18 | TIME_ZONE = 'US/Pacific' |
| 22 | 19 | ||
| 23 | # Language code for this installation. All choices can be found here: |
20 | # Language code for this installation. All choices can be found here: |
| ... | 7 lines hidden [Expand] | ||
| 31 | 28 | ||
| 32 | # If you set this to False, Django will make some optimizations so as not |
29 | # If you set this to False, Django will make some optimizations so as not |
| 33 | # to load the internationalization machinery. |
30 | # to load the internationalization machinery. |
| 34 | USE_I18N = True |
31 | USE_I18N = True |
| 35 | 32 | ||
| 36 | # Enable search. Search needs PyLucene to be installed. It also requires |
||
| 37 | # that a regular job be set up to perform the indexing. To generate the |
||
| 38 | # index, run: |
||
| 39 | # manage.py index |
||
| 40 | # This command will perform an incremental index. To do a full reindex, run: |
||
| 41 | # manage.py index --full |
||
| 42 | # |
||
| 43 | # Incremental indexes should be done fairly often. |
||
| 44 | # A sample cron configuration exists in contrib/conf/search-cron.conf |
||
| 45 | # |
||
| 46 | # If you want the search index to be located somewhere other than the |
||
| 47 | # reviewboard root, set SEARCH_INDEX to the desired path. The index needs to be |
||
| 48 | # a directory writable by the user creating the index and readable by the user |
||
| 49 | # that Review Board runs as. |
||
| 50 | ENABLE_SEARCH = False |
||
| 51 | |||
| 52 | 33 | ||
| 53 | # TLS for LDAP. If you're using LDAP authentication and your LDAP server |
34 | # TLS for LDAP. If you're using LDAP authentication and your LDAP server |
| 54 | # doesn't support ldaps://, you can enable start-TLS with this. |
35 | # doesn't support ldaps://, you can enable start-TLS with this. |
| 55 | LDAP_TLS = False |
36 | LDAP_TLS = False |
| /trunk/reviewboard/urls.py | |||
|---|---|---|---|
| Revision 1421 | New Change | ||
| 1 |
|
1 |
|
| 2 | 2 | ||
| 3 | from django.conf import settings |
3 | from django.conf import settings |
| 4 | from django.conf.urls.defaults import patterns, include, url |
4 | from django.conf.urls.defaults import patterns, include, url |
| 5 | from django.contrib import admin |
5 | from django.contrib import admin |
| 6 | 6 | ||
| 7 | from reviewboard.admin.checks import check_updates_required |
7 | from reviewboard.admin.checks import check_updates_required |
| 8 | from reviewboard.admin.siteconfig import load_site_config |
||
| 8 | from reviewboard.reviews.feeds import RssReviewsFeed, AtomReviewsFeed, \ |
9 | from reviewboard.reviews.feeds import RssReviewsFeed, AtomReviewsFeed, \ |
| 9 | RssSubmitterReviewsFeed, \ |
10 | RssSubmitterReviewsFeed, \ |
| 10 | AtomSubmitterReviewsFeed, \ |
11 | AtomSubmitterReviewsFeed, \ |
| 11 | RssGroupReviewsFeed, \ |
12 | RssGroupReviewsFeed, \ |
| 12 | AtomGroupReviewsFeed |
13 | AtomGroupReviewsFeed |
| 13 | 14 | ||
| 14 | 15 | ||
| 16 | # Load all site settings. |
||
| 17 | load_site_config() |
||
| 18 | |||
| 15 | # Load in all the models for the admin UI. |
19 | # Load in all the models for the admin UI. |
| 16 | if not admin.site._registry: |
20 | if not admin.site._registry: |
| 17 | admin.autodiscover() |
21 | admin.autodiscover() |
| 18 | 22 | ||
| 19 | 23 | ||
| ... | 36 lines hidden [Expand] | ||
| 56 | } |
60 | } |
| 57 | 61 | ||
| 58 | 62 | ||
| 59 | # Main includes |
63 | # Main includes |
| 60 | urlpatterns += patterns('', |
64 | urlpatterns += patterns('', |
| 65 | (r'^account/', include('reviewboard.accounts.urls')), |
||
| 61 | (r'^api/json/', include('reviewboard.webapi.urls')), |
66 | (r'^api/json/', include('reviewboard.webapi.urls')), |
| 62 | (r'^r/', include('reviewboard.reviews.urls')), |
67 | (r'^r/', include('reviewboard.reviews.urls')), |
| 63 | (r'^reports/', include('reviewboard.reports.urls')), |
68 | (r'^reports/', include('reviewboard.reports.urls')), |
| 64 | ) |
69 | ) |
| 65 | 70 | ||
| ... | 33 lines hidden [Expand] | ||
| 99 | urlpatterns += patterns('', |
104 | urlpatterns += patterns('', |
| 100 | url(r'^$', 'django.views.generic.simple.redirect_to', |
105 | url(r'^$', 'django.views.generic.simple.redirect_to', |
| 101 | {'url': 'dashboard/'}, |
106 | {'url': 'dashboard/'}, |
| 102 | name="root"), |
107 | name="root"), |
| 103 | 108 | ||
| 104 | # Authentication and accounts |
||
| 105 | url(r'^account/login/$', 'djblets.auth.views.login', |
||
| 106 | {'next_page': settings.SITE_ROOT + 'dashboard/', |
||
| 107 | 'extra_context': {'BUILTIN_AUTH': settings.BUILTIN_AUTH}}, |
||
| 108 | name="login"), |
||
| 109 | url(r'^account/preferences/$', |
||
| 110 | 'reviewboard.accounts.views.user_preferences', |
||
| 111 | name="user-preferences"), |
||
| 112 | |||
| 113 | # This must be last. |
109 | # This must be last. |
| 114 | (r'^iphone/', include('reviewboard.iphone.urls')), |
110 | (r'^iphone/', include('reviewboard.iphone.urls')), |
| 115 | ) |
111 | ) |
| 116 | |||
| 117 | if settings.BUILTIN_AUTH: |
||
| 118 | urlpatterns += patterns('', |
||
| 119 | url(r'^account/register/$', 'djblets.auth.views.register', |
||
| 120 | {'next_page': settings.SITE_ROOT + 'dashboard/'}, |
||
| 121 | name="register"), |
||
| 122 | ) |
||
| 123 | else: |
||
| 124 | urlpatterns += patterns('', |
||
| 125 | (r'^account/register/$', |
||
| 126 | 'django.views.generic.simple.redirect_to', |
||
| 127 | {'url': settings.SITE_ROOT + 'account/login/'})) |
||
| /trunk/reviewboard/accounts/backends.py | |||
|---|---|---|---|
| Revision 1421 | New Change | ||
| ... | 87 lines hidden [Expand] | ||
| 88 | ldapo.simple_bind_s(settings.LDAP_ANON_BIND_UID, settings.LDAP_ANON_BIND_PASSWD) |
88 | ldapo.simple_bind_s(settings.LDAP_ANON_BIND_UID, settings.LDAP_ANON_BIND_PASSWD) |
| 89 | 89 | ||
| 90 | passwd = ldapo.search_s(settings.LDAP_UID_MASK % username, |
90 | passwd = ldapo.search_s(settings.LDAP_UID_MASK % username, |
| 91 | ldap.SCOPE_SUBTREE, "objectclass=*") |
91 | ldap.SCOPE_SUBTREE, "objectclass=*") |
| 92 | 92 | ||
| 93 | first_name = passwd[0][1]['givenName'][0] |
93 | first_name = passwd[0][1]['givenName'] |
| 94 | last_name = passwd[0][1]['sn'][0] |
94 | last_name = passwd[0][1]['sn'] |
| 95 | email = u'%s@%s' % (username, settings.LDAP_EMAIL_DOMAIN) |
95 | email = u'%s@%s' % (username, settings.LDAP_EMAIL_DOMAIN) |
| 96 | 96 | ||
| 97 | user = User(username=username, |
97 | user = User(username=username, |
| 98 | password='', |
98 | password='', |
| 99 | first_name=first_name, |
99 | first_name=first_name, |
| ... | 20 lines hidden [Expand] | ||
| /trunk/reviewboard/accounts/decorators.py | |||
|---|---|---|---|
| Revision 1421 | New Change | ||
| 1 |
|
1 |
|
| 2 | 2 | ||
| 3 | from django.conf import settings |
||
| 4 | from django.contrib.auth import REDIRECT_FIELD_NAME |
3 | from django.contrib.auth import REDIRECT_FIELD_NAME |
| 5 | from django.core.urlresolvers import reverse |
4 | from django.core.urlresolvers import reverse |
| 6 | from django.http import HttpResponseRedirect |
5 | from django.http import HttpResponseRedirect |
| 7 | 6 | ||
| 8 | from djblets.auth.util import login_required |
7 | from djblets.auth.util import login_required |
| 8 | from djblets.siteconfig.models import SiteConfiguration |
||
| 9 | from djblets.util.decorators import simple_decorator |
9 | from djblets.util.decorators import simple_decorator |
| 10 | 10 | ||
| 11 | from reviewboard.accounts.models import Profile |
11 | from reviewboard.accounts.models import Profile |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | @simple_decorator |
14 | @simple_decorator |
| 15 | def check_login_required(view_func): |
15 | def check_login_required(view_func): |
| 16 | """ |
16 | """ |
| 17 | A decorator that checks whether login is required on this installation |
17 | A decorator that checks whether login is required on this installation |
| 18 | and, if so, checks if the user is logged in. If login is required and |
18 | and, if so, checks if the user is logged in. If login is required and |
| 19 | the user is not logged in, they're redirected to the login link. |
19 | the user is not logged in, they're redirected to the login link. |
| 20 | """ |
20 | """ |
| 21 | def _check(*args, **kwargs): |
21 | def _check(*args, **kwargs): |
| 22 | if settings.REQUIRE_SITEWIDE_LOGIN: |
22 | siteconfig = SiteConfiguration.objects.get_current() |
| 23 | |||
| 24 | if siteconfig.get("auth_require_sitewide_login"): |
||
| 23 | return login_required(view_func)(*args, **kwargs) |
25 | return login_required(view_func)(*args, **kwargs) |
| 24 | else: |
26 | else: |
| 25 | return view_func(*args, **kwargs) |
27 | return view_func(*args, **kwargs) |
| 26 | 28 | ||
| 27 | return _check |
29 | return _check |
| ... | 23 lines hidden [Expand] | ||




