420
									
								
								CHANGELOG.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										420
									
								
								CHANGELOG.rst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,420 @@
 | 
				
			|||||||
 | 
					Change Log
 | 
				
			||||||
 | 
					##########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All notable changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. contents:: Table of Contents
 | 
				
			||||||
 | 
					   :depth: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.7.0 - 2016-08-24
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add a CHANGELOG.rst file.
 | 
				
			||||||
 | 
					* Add a validator to models CharField that should be regular expressions checking that user input
 | 
				
			||||||
 | 
					  are valids regular expressions.
 | 
				
			||||||
 | 
					* Add a CAS_INFO_MESSAGES and CAS_INFO_MESSAGES_ORDER settings allowing to display messages in
 | 
				
			||||||
 | 
					  info-boxes on the html pages of the default templates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Allow the user defined CAS_COMPONENT_URLS to omit not changed values.
 | 
				
			||||||
 | 
					* replace code-block without language indication by literal blocks.
 | 
				
			||||||
 | 
					* Update french translation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Some README.rst typos.
 | 
				
			||||||
 | 
					* some english typos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.6.4 - 2016-08-14
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 282e3a831b3c0b0818881c2f16d056850d572b89
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add a forgotten migration (only change help_text)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.6.3 - 2016-08-14
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 07a537b403c5c5e39a4ddd084f90e3a4de88a54e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add powered by footer
 | 
				
			||||||
 | 
					* Add a github version badge
 | 
				
			||||||
 | 
					* documents templatetags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Usage of the documented API for models _meta in auth.DjangoAuthUser
 | 
				
			||||||
 | 
					* set warn cookie using javascript if possible
 | 
				
			||||||
 | 
					* Unfold many to many attributes in auth.DjangoAuthUser attributes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* typos in README.rst
 | 
				
			||||||
 | 
					* w3c validation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cleaned
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Code factorisation (models.py, views.py)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.6.2 - 2016-08-02
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 773707e6c3c3fa20f697c946e31cafc591e8fee8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Support authentication renewal in federate mode
 | 
				
			||||||
 | 
					* Add new version email and info box then new version is available
 | 
				
			||||||
 | 
					* Add SqlAuthUser and LdapAuthUser auth classes.
 | 
				
			||||||
 | 
					  Deprecate the usage of MysqlAuthUser in favor of SqlAuthUser.
 | 
				
			||||||
 | 
					* Add pytest-warning to tests
 | 
				
			||||||
 | 
					* Add a checkbox to forget the identity provider if we checked "remember the identity provider"
 | 
				
			||||||
 | 
					* Add dependancies correspondance between python pypi, debian and centos packages in README
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Move coverage computation last in travis
 | 
				
			||||||
 | 
					* Enable logging to stderr then running tests
 | 
				
			||||||
 | 
					* Remember "warn me before…" using a cookie
 | 
				
			||||||
 | 
					* Put favicon (shortcut icon) URL in settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Deprecated
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					* The auth class MysqlAuthUser is deprecated in favor of the SqlAuthUser class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Use custom templatetags instead settings custom attributes to Boundfields
 | 
				
			||||||
 | 
					  (As it do not work with django 1.7)
 | 
				
			||||||
 | 
					* Display an error message on bad response from identity provider in federate mode
 | 
				
			||||||
 | 
					  instead of crashing. (e.g. Bad XML document)
 | 
				
			||||||
 | 
					* Catch base64 decode error on b64decode to raise our custom exception BadHash
 | 
				
			||||||
 | 
					* Add secret as sensitive variables/post parameter for /auth
 | 
				
			||||||
 | 
					* Only set "remember my provider" in federated mode upon successful authentication
 | 
				
			||||||
 | 
					* Since we drop django-boostrap3 dependancies, Django default minimal version is 1.7.1
 | 
				
			||||||
 | 
					* [cas.py] Append renew=true when validating tickets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cleaned
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* code factorization (cas.py, forms.py)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.6.1 - 2016-07-27
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: b168e0a6423c53de31aae6c444fa1d1c5083afa6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add sphinx docs + autodoc
 | 
				
			||||||
 | 
					* Add the possibility to run tests with "setup.py test"
 | 
				
			||||||
 | 
					* Include docs, Makefile, coverage config and tests config to source package
 | 
				
			||||||
 | 
					* Add serviceValidate ProxyTicket tests
 | 
				
			||||||
 | 
					* Add python 3.5 tox/travis tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Use https://badges.genua.fr for badges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Keep LoginTicket list upon fail authentication
 | 
				
			||||||
 | 
					  (It prevent the next login attemps to fail because of bad LT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cleaned
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Compact federated mode migration
 | 
				
			||||||
 | 
					* Reformat default_settings.py for documentation using sphinx autodoc
 | 
				
			||||||
 | 
					* Factorize some code (from views.py to Ticket models class methods)
 | 
				
			||||||
 | 
					* Update urlpattern for django 1.10
 | 
				
			||||||
 | 
					* Drop dependancies django-picklefield and django-bootstrap3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.6.0 - 2016-07-06
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 4ad4d13baa4236c5cd72cc5216d7ff08dd361476
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add a section describing service patterns options to README.rst
 | 
				
			||||||
 | 
					* Add a federation mode:
 | 
				
			||||||
 | 
					  When the settings CAS_FEDERATE is True, django-cas-server will offer to the user to choose its
 | 
				
			||||||
 | 
					  CAS backend to authenticate. Hence the login page do not display anymore a username/password form
 | 
				
			||||||
 | 
					  but a select form with configured CASs backend.
 | 
				
			||||||
 | 
					  This allow to give access to CAS supported applications to users from multiple organization
 | 
				
			||||||
 | 
					  seamlessly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  It was originally developped to mach the need of https://ares.fr (Federated CAS at
 | 
				
			||||||
 | 
					  https://cas.ares.fr, example of an application using it as https://chat.myares.fr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Then a ticket was marked as obtained with the user entering its credentials (aka not by SSO), and
 | 
				
			||||||
 | 
					  the service did not require it, ticket validation was failing. Now, if the service do not require
 | 
				
			||||||
 | 
					  authentication to be renewed, both ticket with renewed authentication and non renewed
 | 
				
			||||||
 | 
					  authentication validate successfully.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.5.0 - 2016-07-01
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: e3ab64271b718a17e4cbbbabda0a2453107a83df
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add more password scheme support to the mysql authentication backend: ldap user
 | 
				
			||||||
 | 
					  attribute scheme encoding and simple password hash in hexa for md5, sha1, sha224,
 | 
				
			||||||
 | 
					  sha256, sha384, sha512.
 | 
				
			||||||
 | 
					* Add a main heading to template "Central Authentication Service" with a logo controled
 | 
				
			||||||
 | 
					  by CAS_LOGO_URL
 | 
				
			||||||
 | 
					* Add logos to the project (svg, png)
 | 
				
			||||||
 | 
					* Add coverage computation
 | 
				
			||||||
 | 
					* link project to codacy
 | 
				
			||||||
 | 
					* Update doc: add debian requirement, correct typos, correct links
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Use settings to set tests username password and attributes
 | 
				
			||||||
 | 
					* Tweak the css and html for small screens
 | 
				
			||||||
 | 
					* Update travis cache for faster build
 | 
				
			||||||
 | 
					* clean Makefile, use pip to install, add target for tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Fix "warn me": we generate the ticket after the user agree to be connected to the service.
 | 
				
			||||||
 | 
					  we were generating first and the connect button was a link to the service url with the ?ticket=
 | 
				
			||||||
 | 
					  this could lead to situation where the ticket validity expire if the user is slow to click the
 | 
				
			||||||
 | 
					  connect button.
 | 
				
			||||||
 | 
					* Fix authentication renewal: the renew parameter were not transmited when POST the login request
 | 
				
			||||||
 | 
					   and self.renew (aks for auth renewal) was use instead of self.renewed (auth was renewd)
 | 
				
			||||||
 | 
					   when generating a ticket.
 | 
				
			||||||
 | 
					* Fix attribute value replacement when generating a ticket: we were using the 'name' attribute
 | 
				
			||||||
 | 
					  instead of the 'attribut' attribut on ReplaceAttributValue
 | 
				
			||||||
 | 
					* Fix attribute value replacement when generating a ticket then the value is a list: iterate over
 | 
				
			||||||
 | 
					  each element of the list.
 | 
				
			||||||
 | 
					* Fix a NameError in utils.import_attr
 | 
				
			||||||
 | 
					* Fix serviceValidate and samlValidate when user_field is an attribute that is a list: we use
 | 
				
			||||||
 | 
					  the first element of the list as username. we were serializing the list before that.
 | 
				
			||||||
 | 
					* Correct typos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cleaned
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Clean some useless conditional branches found with coverage
 | 
				
			||||||
 | 
					* Clean cas.js: use compact object declararion
 | 
				
			||||||
 | 
					* Use six for python{2|3} compatibility
 | 
				
			||||||
 | 
					* Move all unit tests to cas_server.tests and use django primitive. We also have a 100% tests
 | 
				
			||||||
 | 
					  coverage now. Using the django classes for tests, we do not need to use our own dirty mock.
 | 
				
			||||||
 | 
					* Move mysql backend password check to a function in utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.4.4 - 2016-04-30
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 77d1607b0beefe8b171adcd8e2dcd974e3cdc72a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add sensitive_post_parameters and sensitive_variables for passwords, so passwords are anonymised
 | 
				
			||||||
 | 
					  before django send an error report.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Before commit 77fc5b5 the User model had a foreign key to the Session model. After the commit,
 | 
				
			||||||
 | 
					  Only the session_key is store, allowing to use different backend than the Session SQL backend.
 | 
				
			||||||
 | 
					  So the first migration (which is 21 migrations combined) was creating the User model with the
 | 
				
			||||||
 | 
					  foreign key, then delete it and add the field session_key. Somehow, MySQL did not like it.
 | 
				
			||||||
 | 
					  Now the first migration directly create the User model with the session_key and without the
 | 
				
			||||||
 | 
					  foreign key to the Session SQL backend.
 | 
				
			||||||
 | 
					* Evaluate attributes variables in the template samlValidate.xml. the {{ }} was missing causing
 | 
				
			||||||
 | 
					  the variable name to be displyed instead of the variable content.
 | 
				
			||||||
 | 
					* Return username in CAS 1.0 on the second ligne of the CAS response as specified.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Update tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.4.3 - 2016-03-18
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: f6d436acb49f8d32b5457c316c18c4892accfd3b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Currently, one of our dependancy, django-boostrap3, do not support django 1.7 in its last version.
 | 
				
			||||||
 | 
					  So there is some detection of the current django installed version in setup.py to pin 
 | 
				
			||||||
 | 
					  django-boostrap3 to a version supported by django 1.7 if django 1.7 is installed, or to require
 | 
				
			||||||
 | 
					  at least django 1.8.
 | 
				
			||||||
 | 
					  The detection did not handle the case where django was not installed.
 | 
				
			||||||
 | 
					* [PEP8] Put line breaks after binary operator and not before.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.4.2 - 2016-03-18
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: d1cd17d6103281b03a8c57013671057eab80d21c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* On logout, display the number of sessions we are logged out from.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* One of our dependancy, django-boostrap3, do not support django 1.7 in its last version.
 | 
				
			||||||
 | 
					  Some django version detection is added to setup.py to handle that.
 | 
				
			||||||
 | 
					* Some typos
 | 
				
			||||||
 | 
					* Make errors returned by utils.import_attr clearer (as they are likely to be displayed to the
 | 
				
			||||||
 | 
					  django admin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.4.1 - 2015-12-23
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 5e63f39f9b7c678a300ad2f8132166be34d1d35b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add a run_test_server target to make file. Running make run_test_server will build a virtualenv,
 | 
				
			||||||
 | 
					  create a django projet with django-cas-server and lauch ./management.py runserver. It is quite
 | 
				
			||||||
 | 
					  handy to test developement version.
 | 
				
			||||||
 | 
					* Add verbose name for cas_server app and models
 | 
				
			||||||
 | 
					* Add Makefile clean targets for tox tests and test virtualenv.
 | 
				
			||||||
 | 
					* Add link on license badge to the GPLv3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Make Makefile clean targets modular
 | 
				
			||||||
 | 
					* Use img.shields.io for PyPi badges
 | 
				
			||||||
 | 
					* Get django-cas-server version in Makefile directly from setup.py (so now, the version is only
 | 
				
			||||||
 | 
					  written in one place)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Fix MysqlAuthUser when number of results != 1: In that case, call super anyway this the provided
 | 
				
			||||||
 | 
					  username.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.4.0 - 2015-12-15
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 7b4fac575449e50c2caff07f5798dba7f4e4857c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add a help_text to pattern of ServicePattern
 | 
				
			||||||
 | 
					* Add a timeout to SLO requests
 | 
				
			||||||
 | 
					* Add logging capabilities (see README.rst for instruction)
 | 
				
			||||||
 | 
					* Add management commands that should be called on a regular basis to README.rst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.3.5 - 2015-12-12
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 51fa0861f550723171e52d58025fa789dccb8cde
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add badges to README.rst
 | 
				
			||||||
 | 
					* Document settings parameter in README.rst
 | 
				
			||||||
 | 
					* Add a "Features" section in README.rst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Changed
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					* Add a AuthUser auth class and use it as auth classes base class instead of DummyAuthUser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Fix minor errors and typos in README.rst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.3.4 - 2015-12-12
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 9fbfe19c550b147e8d0377108cdac8231cf0fb27
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add static files, templates and locales to the PyPi release by adding them to MANIFEST.in
 | 
				
			||||||
 | 
					* Add a Makefile with the build/install/clean/dist targets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.3.3 - 2015-12-12
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 16b700d0127abe33a1eabf5d5fe890aeb5167e5a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add management commands and migrations to the package by adding there packages to setup.py
 | 
				
			||||||
 | 
					  packages list.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.3.2 - 2015-12-12 [YANKED]
 | 
				
			||||||
 | 
					============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: eef9490885bf665a53349573ddb9cbe844319b3e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add migrations to setup.py package_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.3.1 - 2015-12-12
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: d0f6ed9ea3a4b3e2bf715fd218c460892c32e39f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Add a forgotten migration (remove auto_now_add=True from the User model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.3.0 - 2015-12-12
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: b69769d71a99806a69e300eca0d7c6744a2b327e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Added
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Django 1.9 compatibility (add tox and travis tests and fix some decrecated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.2.1 - 2015-12-12
 | 
				
			||||||
 | 
					===================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 90e077dedb991d651822e9bb283470de8bddd7dd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First github and PyPi release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Fixed
 | 
				
			||||||
 | 
					-----
 | 
				
			||||||
 | 
					* Prune .tox in MANIFEST.in
 | 
				
			||||||
 | 
					* add dist/ to .gitignore
 | 
				
			||||||
 | 
					* typo in setup.cfg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.2.0 - 2015-12-12 [YANKED]
 | 
				
			||||||
 | 
					============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: a071ad46d7cd76fc97eb86f2f538d330457c6767
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					v0.1.0 - 2015-05-22 [YANKED]
 | 
				
			||||||
 | 
					============================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit: 6981433bdf8a406992ba0c5e844a47d06ccc08fb
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
include tox.ini
 | 
					include tox.ini
 | 
				
			||||||
include LICENSE
 | 
					include LICENSE
 | 
				
			||||||
include README.rst
 | 
					include README.rst
 | 
				
			||||||
 | 
					include CHANGELOG.rst
 | 
				
			||||||
include .coveragerc
 | 
					include .coveragerc
 | 
				
			||||||
include Makefile
 | 
					include Makefile
 | 
				
			||||||
include pytest.ini
 | 
					include pytest.ini
 | 
				
			||||||
@@ -15,6 +16,7 @@ include docs/conf.py
 | 
				
			|||||||
include docs/index.rst
 | 
					include docs/index.rst
 | 
				
			||||||
include docs/Makefile
 | 
					include docs/Makefile
 | 
				
			||||||
include docs/README.rst
 | 
					include docs/README.rst
 | 
				
			||||||
 | 
					include docs/CHANGELOG.rst
 | 
				
			||||||
recursive-include docs/_ext *
 | 
					recursive-include docs/_ext *
 | 
				
			||||||
recursive-include docs/package *
 | 
					recursive-include docs/package *
 | 
				
			||||||
recursive-include docs/_static *
 | 
					recursive-include docs/_static *
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										62
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								README.rst
									
									
									
									
									
								
							@@ -7,7 +7,7 @@ CAS Server is a Django application implementing the `CAS Protocol 3.0 Specificat
 | 
				
			|||||||
<https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol-Specification.html>`_.
 | 
					<https://apereo.github.io/cas/4.2.x/protocol/CAS-Protocol-Specification.html>`_.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
By default, the authentication process use django internal users but you can easily
 | 
					By default, the authentication process use django internal users but you can easily
 | 
				
			||||||
use any sources (see auth classes in the auth.py file)
 | 
					use any sources (see the `Authentication backend`_ section and auth classes in the auth.py file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. contents:: Table of Contents
 | 
					.. contents:: Table of Contents
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,7 +38,7 @@ Dependencies
 | 
				
			|||||||
Minimal version of packages dependancy are just indicative and meens that ``django-cas-server`` has
 | 
					Minimal version of packages dependancy are just indicative and meens that ``django-cas-server`` has
 | 
				
			||||||
been tested with it. Previous versions of dependencies may or may not work.
 | 
					been tested with it. Previous versions of dependencies may or may not work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Additionally, denpending of the authentication backend you plan to use, you may need the following
 | 
					Additionally, denpending of the `Authentication backend`_ you plan to use, you may need the following
 | 
				
			||||||
python packages:
 | 
					python packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* ldap3
 | 
					* ldap3
 | 
				
			||||||
@@ -174,13 +174,11 @@ Quick start
 | 
				
			|||||||
     inactive since more than ``SESSION_COOKIE_AGE``. The default value for is ``1209600``
 | 
					     inactive since more than ``SESSION_COOKIE_AGE``. The default value for is ``1209600``
 | 
				
			||||||
     seconds (2 weeks). You probably should reduce it to something like ``86400`` seconds (1 day).
 | 
					     seconds (2 weeks). You probably should reduce it to something like ``86400`` seconds (1 day).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   You could for example do as bellow :
 | 
					   You could for example do as bellow::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   .. code-block::
 | 
					     0   0  * * * cas-user /path/to/project/manage.py clearsessions
 | 
				
			||||||
 | 
					     */5 *  * * * cas-user /path/to/project/manage.py cas_clean_tickets
 | 
				
			||||||
      0   0  * * * cas-user /path/to/project/manage.py clearsessions
 | 
					     5   0  * * * cas-user /path/to/project/manage.py cas_clean_sessions
 | 
				
			||||||
      */5 *  * * * cas-user /path/to/project/manage.py cas_clean_tickets
 | 
					 | 
				
			||||||
      5   0  * * * cas-user /path/to/project/manage.py cas_clean_sessions
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
5. Run ``python manage.py createsuperuser`` to create an administrator user.
 | 
					5. Run ``python manage.py createsuperuser`` to create an administrator user.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -208,7 +206,7 @@ Template settings
 | 
				
			|||||||
  Default is a key icon. Set it to ``False`` to disable it.
 | 
					  Default is a key icon. Set it to ``False`` to disable it.
 | 
				
			||||||
* ``CAS_SHOW_POWERED``: Set it to ``False`` to hide the powered by footer. The default is ``True``.
 | 
					* ``CAS_SHOW_POWERED``: Set it to ``False`` to hide the powered by footer. The default is ``True``.
 | 
				
			||||||
* ``CAS_COMPONENT_URLS``: URLs to css and javascript external components. It is a dictionnary
 | 
					* ``CAS_COMPONENT_URLS``: URLs to css and javascript external components. It is a dictionnary
 | 
				
			||||||
  and it must have the five following keys: ``"bootstrap3_css"``, ``"bootstrap3_js"``,
 | 
					  having the five following keys: ``"bootstrap3_css"``, ``"bootstrap3_js"``,
 | 
				
			||||||
  ``"html5shiv"``, ``"respond"``, ``"jquery"``. The default is::
 | 
					  ``"html5shiv"``, ``"respond"``, ``"jquery"``. The default is::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -219,6 +217,32 @@ Template settings
 | 
				
			|||||||
            "jquery": "//code.jquery.com/jquery.min.js",
 | 
					            "jquery": "//code.jquery.com/jquery.min.js",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if you omit some keys of the dictionnary, the default value for these keys is used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ``CAS_INFO_MESSAGES``: Messages displayed in info-boxes on the html pages of the default templates.
 | 
				
			||||||
 | 
					  It is a dictionnary mapping message name to a message dict. A message dict has 3 keys:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * ``message``: A unicode message to display, potentially wrapped around ugettex_lazy
 | 
				
			||||||
 | 
					  * ``discardable``: A boolean, specify if the users can close the message info-box
 | 
				
			||||||
 | 
					  * ``type``: One of info, success, info, warning, danger. The type of the info-box.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ``CAS_INFO_MESSAGES`` contains by default one message, ``cas_explained``, which explain
 | 
				
			||||||
 | 
					  roughly the purpose of a CAS. The default is::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "cas_explained": {
 | 
				
			||||||
 | 
					            "message":_(
 | 
				
			||||||
 | 
					                u"The Central Authentication Service grants you access to most of our websites by "
 | 
				
			||||||
 | 
					                u"authenticating only once, so you don't need to type your credentials again unless "
 | 
				
			||||||
 | 
					                u"your session expires or you logout."
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            "discardable": True,
 | 
				
			||||||
 | 
					            "type": "info",  # one of info, success, info, warning, danger
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* ``CAS_INFO_MESSAGES_ORDER``: A list of message names. Order in which info-box messages are
 | 
				
			||||||
 | 
					  displayed. Use an empty list to disable messages display. The default is ``[]``.
 | 
				
			||||||
* ``CAS_LOGIN_TEMPLATE``: Path to the template showed on ``/login`` then the user
 | 
					* ``CAS_LOGIN_TEMPLATE``: Path to the template showed on ``/login`` then the user
 | 
				
			||||||
  is not autenticated.  The default is ``"cas_server/login.html"``.
 | 
					  is not autenticated.  The default is ``"cas_server/login.html"``.
 | 
				
			||||||
* ``CAS_WARN_TEMPLATE``: Path to the template showed on ``/login?service=...`` then
 | 
					* ``CAS_WARN_TEMPLATE``: Path to the template showed on ``/login?service=...`` then
 | 
				
			||||||
@@ -228,7 +252,7 @@ Template settings
 | 
				
			|||||||
  authenticated. The default is ``"cas_server/logged.html"``.
 | 
					  authenticated. The default is ``"cas_server/logged.html"``.
 | 
				
			||||||
* ``CAS_LOGOUT_TEMPLATE``: Path to the template showed on ``/logout`` then to user
 | 
					* ``CAS_LOGOUT_TEMPLATE``: Path to the template showed on ``/logout`` then to user
 | 
				
			||||||
  is being disconnected. The default is ``"cas_server/logout.html"``
 | 
					  is being disconnected. The default is ``"cas_server/logout.html"``
 | 
				
			||||||
* ``CAS_REDIRECT_TO_LOGIN_AFTER_LOGOUT``: Should we redirect users to `/login` after they
 | 
					* ``CAS_REDIRECT_TO_LOGIN_AFTER_LOGOUT``: Should we redirect users to ``/login`` after they
 | 
				
			||||||
  logged out instead of displaying ``CAS_LOGOUT_TEMPLATE``. The default is ``False``.
 | 
					  logged out instead of displaying ``CAS_LOGOUT_TEMPLATE``. The default is ``False``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -271,7 +295,7 @@ New version warnings settings
 | 
				
			|||||||
* ``CAS_NEW_VERSION_HTML_WARNING``: A boolean for diplaying a warning on html pages then a new
 | 
					* ``CAS_NEW_VERSION_HTML_WARNING``: A boolean for diplaying a warning on html pages then a new
 | 
				
			||||||
  version of the application is avaible. Once closed by a user, it is not displayed to this user
 | 
					  version of the application is avaible. Once closed by a user, it is not displayed to this user
 | 
				
			||||||
  until the next new version. The default is ``True``.
 | 
					  until the next new version. The default is ``True``.
 | 
				
			||||||
* ``CAS_NEW_VERSION_EMAIL_WARNING``: A bolean sot sending a email to ``settings.ADMINS`` when a new
 | 
					* ``CAS_NEW_VERSION_EMAIL_WARNING``: A boolean for sending a email to ``settings.ADMINS`` when a new
 | 
				
			||||||
  version is available. The default is ``True``.
 | 
					  version is available. The default is ``True``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -545,10 +569,10 @@ A service pattern has 4 associated models:
 | 
				
			|||||||
  an email address to connect to it. To do so, put ``email`` in ``Attribute`` and ``.*`` in ``pattern``.
 | 
					  an email address to connect to it. To do so, put ``email`` in ``Attribute`` and ``.*`` in ``pattern``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Then a user ask a ticket for a service, the service URL is compare against each service patterns
 | 
					Then a user ask a ticket for a service, the service URL is compare against each service patterns
 | 
				
			||||||
sorted by `position`. The first service pattern that matches the service URL is chosen.
 | 
					sorted by ``position``. The first service pattern that matches the service URL is chosen.
 | 
				
			||||||
Hence, you should give low `position` to very specific patterns like
 | 
					Hence, you should give low ``position`` to very specific patterns like
 | 
				
			||||||
``^https://www\.example\.com(/.*)?$`` and higher `position` to generic patterns like ``^https://.*``.
 | 
					``^https://www\.example\.com(/.*)?$`` and higher ``position`` to generic patterns like ``^https://.*``.
 | 
				
			||||||
So the service URL `https://www.examle.com` will use the service pattern for
 | 
					So the service URL ``https://www.examle.com`` will use the service pattern for
 | 
				
			||||||
``^https://www\.example\.com(/.*)?$`` and not the one for ``^https://.*``.
 | 
					``^https://www\.example\.com(/.*)?$`` and not the one for ``^https://.*``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -572,7 +596,7 @@ An identity provider comes with 5 fields:
 | 
				
			|||||||
* ``Suffix``: the suffix that will be append to the username returned by the identity provider.
 | 
					* ``Suffix``: the suffix that will be append to the username returned by the identity provider.
 | 
				
			||||||
  It must be unique.
 | 
					  It must be unique.
 | 
				
			||||||
* ``Server url``: the URL to the identity provider CAS. For instance, if you are using
 | 
					* ``Server url``: the URL to the identity provider CAS. For instance, if you are using
 | 
				
			||||||
  ``https://cas.example.org/login`` to authenticate on the CAS, the `server url` is
 | 
					  ``https://cas.example.org/login`` to authenticate on the CAS, the ``server url`` is
 | 
				
			||||||
  ``https://cas.example.org``
 | 
					  ``https://cas.example.org``
 | 
				
			||||||
* ``CAS protocol version``: the version of the CAS protocol to use to contact the identity provider.
 | 
					* ``CAS protocol version``: the version of the CAS protocol to use to contact the identity provider.
 | 
				
			||||||
  The default is version 3.
 | 
					  The default is version 3.
 | 
				
			||||||
@@ -593,11 +617,9 @@ Then using federate mode, you should add one command to a daily crontab: ``cas_c
 | 
				
			|||||||
This command clean the local cache of federated user from old unused users.
 | 
					This command clean the local cache of federated user from old unused users.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You could for example do as bellow :
 | 
					You could for example do as bellow::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block::
 | 
					  10   0  * * * cas-user /path/to/project/manage.py cas_clean_federate
 | 
				
			||||||
 | 
					 | 
				
			||||||
    10   0  * * * cas-user /path/to/project/manage.py cas_clean_federate
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
"""A django CAS server application"""
 | 
					"""A django CAS server application"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: version of the application
 | 
					#: version of the application
 | 
				
			||||||
VERSION = '0.6.4'
 | 
					VERSION = '0.7.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: path the the application configuration class
 | 
					#: path the the application configuration class
 | 
				
			||||||
default_app_config = 'cas_server.apps.CasAppConfig'
 | 
					default_app_config = 'cas_server.apps.CasAppConfig'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
"""Default values for the app's settings"""
 | 
					"""Default values for the app's settings"""
 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.contrib.staticfiles.templatetags.staticfiles import static
 | 
					from django.contrib.staticfiles.templatetags.staticfiles import static
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from importlib import import_module
 | 
					from importlib import import_module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -180,13 +181,45 @@ CAS_NEW_VERSION_EMAIL_WARNING = True
 | 
				
			|||||||
#: You should not change it.
 | 
					#: You should not change it.
 | 
				
			||||||
CAS_NEW_VERSION_JSON_URL = "https://pypi.python.org/pypi/django-cas-server/json"
 | 
					CAS_NEW_VERSION_JSON_URL = "https://pypi.python.org/pypi/django-cas-server/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: Messages displayed in a info-box on the html pages of the default templates.
 | 
				
			||||||
 | 
					#: ``CAS_INFO_MESSAGES`` is a :class:`dict` mapping message name to a message :class:`dict`.
 | 
				
			||||||
 | 
					#: A message :class:`dict` has 3 keys:
 | 
				
			||||||
 | 
					#:  * ``message``: A :class:`unicode`, the message to display, potentially wrapped around
 | 
				
			||||||
 | 
					#:    ugettex_lazy
 | 
				
			||||||
 | 
					#:  * ``discardable``: A :class:`bool`, specify if the users can close the message info-box
 | 
				
			||||||
 | 
					#:  * ``type``: One of info, success, info, warning, danger. The type of the info-box.
 | 
				
			||||||
 | 
					#: ``CAS_INFO_MESSAGES`` contains by default one message, ``cas_explained``, which explain
 | 
				
			||||||
 | 
					#: roughly the purpose of a CAS.
 | 
				
			||||||
 | 
					CAS_INFO_MESSAGES = {
 | 
				
			||||||
 | 
					    "cas_explained": {
 | 
				
			||||||
 | 
					        "message": _(
 | 
				
			||||||
 | 
					            u"The Central Authentication Service grants you access to most of our websites by "
 | 
				
			||||||
 | 
					            u"authenticating only once, so you don't need to type your credentials again unless "
 | 
				
			||||||
 | 
					            u"your session expires or you logout."
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        "discardable": True,
 | 
				
			||||||
 | 
					        "type": "info",  # one of info, success, info, warning, danger
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#: :class:`list` of message names. Order in which info-box messages are displayed.
 | 
				
			||||||
 | 
					#: Let the list empty to disable messages display.
 | 
				
			||||||
 | 
					CAS_INFO_MESSAGES_ORDER = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLOBALS = globals().copy()
 | 
					GLOBALS = globals().copy()
 | 
				
			||||||
for name, default_value in GLOBALS.items():
 | 
					for name, default_value in GLOBALS.items():
 | 
				
			||||||
    # get the current setting value, falling back to default_value
 | 
					    # only care about parameter begining by CAS_
 | 
				
			||||||
    value = getattr(settings, name, default_value)
 | 
					    if name.startswith("CAS_"):
 | 
				
			||||||
    # set the setting value to its value if defined, ellse to the default_value.
 | 
					        # get the current setting value, falling back to default_value
 | 
				
			||||||
    setattr(settings, name, value)
 | 
					        value = getattr(settings, name, default_value)
 | 
				
			||||||
 | 
					        # set the setting value to its value if defined, ellse to the default_value.
 | 
				
			||||||
 | 
					        setattr(settings, name, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Allow the user defined CAS_COMPONENT_URLS to omit not changed values
 | 
				
			||||||
 | 
					MERGED_CAS_COMPONENT_URLS = CAS_COMPONENT_URLS.copy()
 | 
				
			||||||
 | 
					MERGED_CAS_COMPONENT_URLS.update(settings.CAS_COMPONENT_URLS)
 | 
				
			||||||
 | 
					settings.CAS_COMPONENT_URLS = MERGED_CAS_COMPONENT_URLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# if the federated mode is enabled, we must use the :class`cas_server.auth.CASFederateAuth` auth
 | 
					# if the federated mode is enabled, we must use the :class`cas_server.auth.CASFederateAuth` auth
 | 
				
			||||||
# backend.
 | 
					# backend.
 | 
				
			||||||
 
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							@@ -7,8 +7,8 @@ msgid ""
 | 
				
			|||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: cas_server\n"
 | 
					"Project-Id-Version: cas_server\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2016-08-01 12:01+0200\n"
 | 
					"POT-Creation-Date: 2016-08-24 17:18+0200\n"
 | 
				
			||||||
"PO-Revision-Date: 2016-08-01 12:01+0200\n"
 | 
					"PO-Revision-Date: 2016-08-24 17:18+0200\n"
 | 
				
			||||||
"Last-Translator: Valentin Samir <valentin.samir@crans.org>\n"
 | 
					"Last-Translator: Valentin Samir <valentin.samir@crans.org>\n"
 | 
				
			||||||
"Language-Team: django <LL@li.org>\n"
 | 
					"Language-Team: django <LL@li.org>\n"
 | 
				
			||||||
"Language: fr\n"
 | 
					"Language: fr\n"
 | 
				
			||||||
@@ -18,70 +18,81 @@ msgstr ""
 | 
				
			|||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
 | 
					"Plural-Forms: nplurals=2; plural=(n > 1);\n"
 | 
				
			||||||
"X-Generator: Poedit 1.8.8\n"
 | 
					"X-Generator: Poedit 1.8.8\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: apps.py:25 templates/cas_server/base.html:9
 | 
					#: apps.py:25 templates/cas_server/base.html:7
 | 
				
			||||||
#: templates/cas_server/base.html:27
 | 
					#: templates/cas_server/base.html:26
 | 
				
			||||||
msgid "Central Authentication Service"
 | 
					msgid "Central Authentication Service"
 | 
				
			||||||
msgstr "Service Central d'Authentification"
 | 
					msgstr "Service Central d'Authentification"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:88
 | 
					#: default_settings.py:197
 | 
				
			||||||
 | 
					msgid ""
 | 
				
			||||||
 | 
					"The Central Authentication Service grants you access to most of our websites "
 | 
				
			||||||
 | 
					"by authenticating only once, so you don't need to type your credentials "
 | 
				
			||||||
 | 
					"again unless your session expires or you logout."
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					"Le Service Central d'Authentification permet, en vous authentifiant une "
 | 
				
			||||||
 | 
					"seule fois, d'accéder à la plupart de nos sites sans avoir à retaper votre "
 | 
				
			||||||
 | 
					"identifiant et votre mot de passe chaque fois que vous changez de site, "
 | 
				
			||||||
 | 
					"jusqu'à ce que votre session expire ou que vous vous déconnectiez."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: forms.py:84
 | 
				
			||||||
msgid "Identity provider"
 | 
					msgid "Identity provider"
 | 
				
			||||||
msgstr "fournisseur d'identité"
 | 
					msgstr "fournisseur d'identité"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:92 forms.py:111
 | 
					#: forms.py:88 forms.py:107
 | 
				
			||||||
msgid "Warn me before logging me into other sites."
 | 
					msgid "Warn me before logging me into other sites."
 | 
				
			||||||
msgstr "Prévenez-moi avant d'accéder à d'autres services."
 | 
					msgstr "Prévenez-moi avant d'accéder à d'autres services."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:96
 | 
					#: forms.py:92
 | 
				
			||||||
msgid "Remember the identity provider"
 | 
					msgid "Remember the identity provider"
 | 
				
			||||||
msgstr "Se souvenir du fournisseur d'identité"
 | 
					msgstr "Se souvenir du fournisseur d'identité"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:106 models.py:600
 | 
					#: forms.py:102 models.py:594
 | 
				
			||||||
msgid "username"
 | 
					msgid "username"
 | 
				
			||||||
msgstr "nom d'utilisateur"
 | 
					msgstr "nom d'utilisateur"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:108
 | 
					#: forms.py:104
 | 
				
			||||||
msgid "password"
 | 
					msgid "password"
 | 
				
			||||||
msgstr "mot de passe"
 | 
					msgstr "mot de passe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:130
 | 
					#: forms.py:126
 | 
				
			||||||
msgid "The credentials you provided cannot be determined to be authentic."
 | 
					msgid "The credentials you provided cannot be determined to be authentic."
 | 
				
			||||||
msgstr "Les informations transmises n'ont pas permis de vous authentifier."
 | 
					msgstr "Les informations transmises n'ont pas permis de vous authentifier."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:182
 | 
					#: forms.py:178
 | 
				
			||||||
msgid "User not found in the temporary database, please try to reconnect"
 | 
					msgid "User not found in the temporary database, please try to reconnect"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Utilisateur non trouvé dans la base de donnée temporaire, essayez de vous "
 | 
					"Utilisateur non trouvé dans la base de donnée temporaire, essayez de vous "
 | 
				
			||||||
"reconnecter"
 | 
					"reconnecter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: forms.py:196
 | 
					#: forms.py:192
 | 
				
			||||||
msgid "service"
 | 
					msgid "service"
 | 
				
			||||||
msgstr "service"
 | 
					msgstr "service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: management/commands/cas_clean_federate.py:20
 | 
					#: management/commands/cas_clean_federate.py:20
 | 
				
			||||||
msgid "Clean old federated users"
 | 
					msgid "Clean old federated users"
 | 
				
			||||||
msgstr "Nettoyer les anciens utilisateurs fédéré"
 | 
					msgstr "Nettoyer les anciens utilisateurs fédérés"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: management/commands/cas_clean_sessions.py:22
 | 
					#: management/commands/cas_clean_sessions.py:22
 | 
				
			||||||
msgid "Clean deleted sessions"
 | 
					msgid "Clean deleted sessions"
 | 
				
			||||||
msgstr "Nettoyer les sessions supprimées"
 | 
					msgstr "Nettoyer les sessions supprimées"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: management/commands/cas_clean_tickets.py:22
 | 
					#: management/commands/cas_clean_tickets.py:22
 | 
				
			||||||
msgid "Clean old trickets"
 | 
					msgid "Clean old tickets"
 | 
				
			||||||
msgstr "Nettoyer les vieux tickets"
 | 
					msgstr "Nettoyer les vieux tickets"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:46
 | 
					#: models.py:71
 | 
				
			||||||
msgid "identity provider"
 | 
					msgid "identity provider"
 | 
				
			||||||
msgstr "fournisseur d'identité"
 | 
					msgstr "fournisseur d'identité"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:47
 | 
					#: models.py:72
 | 
				
			||||||
msgid "identity providers"
 | 
					msgid "identity providers"
 | 
				
			||||||
msgstr "fournisseurs d'identités"
 | 
					msgstr "fournisseurs d'identités"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:53
 | 
					#: models.py:78
 | 
				
			||||||
msgid "suffix"
 | 
					msgid "suffix"
 | 
				
			||||||
msgstr "suffixe"
 | 
					msgstr "suffixe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:55
 | 
					#: models.py:80
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"Suffix append to backend CAS returned username: ``returned_username`` @ "
 | 
					"Suffix append to backend CAS returned username: ``returned_username`` @ "
 | 
				
			||||||
"``suffix``."
 | 
					"``suffix``."
 | 
				
			||||||
@@ -89,46 +100,46 @@ msgstr ""
 | 
				
			|||||||
"Suffixe ajouté au nom d'utilisateur retourné par le CAS du fournisseur "
 | 
					"Suffixe ajouté au nom d'utilisateur retourné par le CAS du fournisseur "
 | 
				
			||||||
"d'identité : `nom retourné`@`suffixe`."
 | 
					"d'identité : `nom retourné`@`suffixe`."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:62
 | 
					#: models.py:87
 | 
				
			||||||
msgid "server url"
 | 
					msgid "server url"
 | 
				
			||||||
msgstr "url du serveur"
 | 
					msgstr "url du serveur"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:72
 | 
					#: models.py:97
 | 
				
			||||||
msgid "CAS protocol version"
 | 
					msgid "CAS protocol version"
 | 
				
			||||||
msgstr "Version du protocole CAS"
 | 
					msgstr "Version du protocole CAS"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:74
 | 
					#: models.py:99
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"Version of the CAS protocol to use when sending requests the the backend CAS."
 | 
					"Version of the CAS protocol to use when sending requests the the backend CAS."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Version du protocole CAS à utiliser lorsque l'on envoie des requête au CAS "
 | 
					"Version du protocole CAS à utiliser lorsque l'on envoie des requête au CAS "
 | 
				
			||||||
"du fournisseur d'identité."
 | 
					"du fournisseur d'identité."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:81
 | 
					#: models.py:106
 | 
				
			||||||
msgid "verbose name"
 | 
					msgid "verbose name"
 | 
				
			||||||
msgstr "Nom du fournisseur"
 | 
					msgstr "Nom du fournisseur"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:82
 | 
					#: models.py:107
 | 
				
			||||||
msgid "Name for this identity provider displayed on the login page."
 | 
					msgid "Name for this identity provider displayed on the login page."
 | 
				
			||||||
msgstr "Nom affiché pour ce fournisseur d'identité sur la page de connexion."
 | 
					msgstr "Nom affiché pour ce fournisseur d'identité sur la page de connexion."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:88 models.py:446
 | 
					#: models.py:113 models.py:446
 | 
				
			||||||
msgid "position"
 | 
					msgid "position"
 | 
				
			||||||
msgstr "position"
 | 
					msgstr "position"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:102
 | 
					#: models.py:127
 | 
				
			||||||
msgid "display"
 | 
					msgid "display"
 | 
				
			||||||
msgstr "afficher"
 | 
					msgstr "afficher"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:103
 | 
					#: models.py:128
 | 
				
			||||||
msgid "Display the provider on the login page."
 | 
					msgid "Display the provider on the login page."
 | 
				
			||||||
msgstr "Afficher le fournisseur d'identité sur la page de connexion."
 | 
					msgstr "Afficher le fournisseur d'identité sur la page de connexion."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:233
 | 
					#: models.py:245
 | 
				
			||||||
msgid "User"
 | 
					msgid "User"
 | 
				
			||||||
msgstr "Utilisateur"
 | 
					msgstr "Utilisateur"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:234
 | 
					#: models.py:246
 | 
				
			||||||
msgid "Users"
 | 
					msgid "Users"
 | 
				
			||||||
msgstr "Utilisateurs"
 | 
					msgstr "Utilisateurs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -149,7 +160,7 @@ msgstr "Motifs de services"
 | 
				
			|||||||
msgid "service patterns are sorted using the position attribute"
 | 
					msgid "service patterns are sorted using the position attribute"
 | 
				
			||||||
msgstr "Les motifs de service sont trié selon l'attribut position"
 | 
					msgstr "Les motifs de service sont trié selon l'attribut position"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:455 models.py:626
 | 
					#: models.py:455 models.py:620
 | 
				
			||||||
msgid "name"
 | 
					msgid "name"
 | 
				
			||||||
msgstr "nom"
 | 
					msgstr "nom"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,7 +168,7 @@ msgstr "nom"
 | 
				
			|||||||
msgid "A name for the service"
 | 
					msgid "A name for the service"
 | 
				
			||||||
msgstr "Un nom pour le service"
 | 
					msgstr "Un nom pour le service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:464 models.py:669 models.py:698
 | 
					#: models.py:464 models.py:663 models.py:693
 | 
				
			||||||
msgid "pattern"
 | 
					msgid "pattern"
 | 
				
			||||||
msgstr "motif"
 | 
					msgstr "motif"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -172,108 +183,108 @@ msgstr ""
 | 
				
			|||||||
"expression rationnelle, les caractères spéciaux doivent être échappés avec "
 | 
					"expression rationnelle, les caractères spéciaux doivent être échappés avec "
 | 
				
			||||||
"un '\\'."
 | 
					"un '\\'."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:476
 | 
					#: models.py:477
 | 
				
			||||||
msgid "user field"
 | 
					msgid "user field"
 | 
				
			||||||
msgstr "champ utilisateur"
 | 
					msgstr "champ utilisateur"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:477
 | 
					#: models.py:478
 | 
				
			||||||
msgid "Name of the attribute to transmit as username, empty = login"
 | 
					msgid "Name of the attribute to transmit as username, empty = login"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Nom de l'attribut devant être transmis comme nom d'utilisateur au service. "
 | 
					"Nom de l'attribut devant être transmis comme nom d'utilisateur au service. "
 | 
				
			||||||
"vide = nom de connexion"
 | 
					"vide = nom de connexion"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:482
 | 
					#: models.py:483
 | 
				
			||||||
msgid "restrict username"
 | 
					msgid "restrict username"
 | 
				
			||||||
msgstr "limiter les noms d'utilisateurs"
 | 
					msgstr "limiter les noms d'utilisateurs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:483
 | 
					#: models.py:484
 | 
				
			||||||
msgid "Limit username allowed to connect to the list provided bellow"
 | 
					msgid "Limit username allowed to connect to the list provided bellow"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Limiter les noms d'utilisateurs autorisé à se connecter à la liste fournie "
 | 
					"Limiter les noms d'utilisateurs autorisé à se connecter à la liste fournie "
 | 
				
			||||||
"ci-dessous"
 | 
					"ci-dessous"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:488
 | 
					#: models.py:489
 | 
				
			||||||
msgid "proxy"
 | 
					msgid "proxy"
 | 
				
			||||||
msgstr "proxy"
 | 
					msgstr "proxy"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:489
 | 
					#: models.py:490
 | 
				
			||||||
msgid "Proxy tickets can be delivered to the service"
 | 
					msgid "Proxy tickets can be delivered to the service"
 | 
				
			||||||
msgstr "des proxy tickets peuvent être délivrés au service"
 | 
					msgstr "des proxy tickets peuvent être délivrés au service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:495
 | 
					#: models.py:496
 | 
				
			||||||
msgid "proxy callback"
 | 
					msgid "proxy callback"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:496
 | 
					#: models.py:497
 | 
				
			||||||
msgid "can be used as a proxy callback to deliver PGT"
 | 
					msgid "can be used as a proxy callback to deliver PGT"
 | 
				
			||||||
msgstr "peut être utilisé comme un callback pour recevoir un PGT"
 | 
					msgstr "peut être utilisé comme un callback pour recevoir un PGT"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:503
 | 
					#: models.py:504
 | 
				
			||||||
msgid "single log out"
 | 
					msgid "single log out"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:504
 | 
					#: models.py:505
 | 
				
			||||||
msgid "Enable SLO for the service"
 | 
					msgid "Enable SLO for the service"
 | 
				
			||||||
msgstr "Active le SLO pour le service"
 | 
					msgstr "Active le SLO pour le service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:512
 | 
					#: models.py:513
 | 
				
			||||||
msgid "single log out callback"
 | 
					msgid "single log out callback"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:513
 | 
					#: models.py:514
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"URL where the SLO request will be POST. empty = service url\n"
 | 
					"URL where the SLO request will be POST. empty = service url\n"
 | 
				
			||||||
"This is usefull for non HTTP proxied services."
 | 
					"This is usefull for non HTTP proxied services."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"URL a laquelle la requête de déconnexion sera postée. vide = l'url du "
 | 
					"URL à laquelle la requête de déconnexion sera postée. vide = l'url du "
 | 
				
			||||||
"service\n"
 | 
					"service\n"
 | 
				
			||||||
"Ceci n'est utilise que pour des services non HTTP proxifiés"
 | 
					"Ceci n'est en général utilisé que pour des services non HTTP proxifiés"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:601
 | 
					#: models.py:595
 | 
				
			||||||
msgid "username allowed to connect to the service"
 | 
					msgid "username allowed to connect to the service"
 | 
				
			||||||
msgstr "noms d'utilisateurs autorisé à se connecter au service"
 | 
					msgstr "noms d'utilisateurs autorisés à se connecter au service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:627
 | 
					#: models.py:621
 | 
				
			||||||
msgid "name of an attribute to send to the service, use * for all attributes"
 | 
					msgid "name of an attribute to send to the service, use * for all attributes"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"nom d'un attribut a envoyer au service, utiliser * pour tous les attributs"
 | 
					"nom d'un attribut à envoyer au service, utiliser * pour tous les attributs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:634 models.py:705
 | 
					#: models.py:628 models.py:701
 | 
				
			||||||
msgid "replace"
 | 
					msgid "replace"
 | 
				
			||||||
msgstr "remplacement"
 | 
					msgstr "remplacement"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:635
 | 
					#: models.py:629
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"name under which the attribute will be showto the service. empty = default "
 | 
					"name under which the attribute will be show to the service. empty = default "
 | 
				
			||||||
"name of the attribut"
 | 
					"name of the attribut"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"nom sous lequel l'attribut sera rendu visible au service. vide = inchangé"
 | 
					"nom sous lequel l'attribut sera rendu visible au service. vide = inchangé"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:662 models.py:692
 | 
					#: models.py:656 models.py:687
 | 
				
			||||||
msgid "attribute"
 | 
					msgid "attribute"
 | 
				
			||||||
msgstr "attribut"
 | 
					msgstr "attribut"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:663
 | 
					#: models.py:657
 | 
				
			||||||
msgid "Name of the attribute which must verify pattern"
 | 
					msgid "Name of the attribute which must verify pattern"
 | 
				
			||||||
msgstr "Nom de l'attribut devant vérifier un motif"
 | 
					msgstr "Nom de l'attribut devant vérifier un motif"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:670
 | 
					#: models.py:664
 | 
				
			||||||
msgid "a regular expression"
 | 
					msgid "a regular expression"
 | 
				
			||||||
msgstr "une expression régulière"
 | 
					msgstr "une expression régulière"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:693
 | 
					#: models.py:688
 | 
				
			||||||
msgid "Name of the attribute for which the value must be replace"
 | 
					msgid "Name of the attribute for which the value must be replace"
 | 
				
			||||||
msgstr "nom de l'attribut pour lequel la valeur doit être remplacé"
 | 
					msgstr "Nom de l'attribut pour lequel la valeur doit être remplacé"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:699
 | 
					#: models.py:694
 | 
				
			||||||
msgid "An regular expression maching whats need to be replaced"
 | 
					msgid "An regular expression maching whats need to be replaced"
 | 
				
			||||||
msgstr "une expression régulière reconnaissant ce qui doit être remplacé"
 | 
					msgstr "Une expression régulière reconnaissant ce qui doit être remplacé"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models.py:706
 | 
					#: models.py:702
 | 
				
			||||||
msgid "replace expression, groups are capture by \\1, \\2 …"
 | 
					msgid "replace expression, groups are capture by \\1, \\2 …"
 | 
				
			||||||
msgstr "expression de remplacement, les groupe sont capturé par \\1, \\2"
 | 
					msgstr "expression de remplacement, les groupe sont capturé par \\1, \\2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/cas_server/base.html:38
 | 
					#: templates/cas_server/base.html:43
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"A new version of the application is available. This instance runs "
 | 
					"A new version of the application is available. This instance runs "
 | 
				
			||||||
@@ -282,7 +293,7 @@ msgid ""
 | 
				
			|||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Une nouvelle version de l'application est disponible. Cette instance utilise "
 | 
					"Une nouvelle version de l'application est disponible. Cette instance utilise "
 | 
				
			||||||
"la version %(VERSION)s et la dernière version est %(LAST_VERSION)s. Merci de "
 | 
					"la version %(VERSION)s et la dernière version est %(LAST_VERSION)s. Merci de "
 | 
				
			||||||
"vous mettre a jour."
 | 
					"vous mettre à jour."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/cas_server/logged.html:4
 | 
					#: templates/cas_server/logged.html:4
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
@@ -291,10 +302,10 @@ msgid ""
 | 
				
			|||||||
"your web browser when you are done accessing services that require "
 | 
					"your web browser when you are done accessing services that require "
 | 
				
			||||||
"authentication!"
 | 
					"authentication!"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"<h3>Déconnexion réussie</h3>Vous vous êtes déconnecté(e) du Service Central "
 | 
					"<h3>Connexion réussie</h3>Vous vous êtes connecté(e) auprès du Service "
 | 
				
			||||||
"d'Authentification. Pour des raisons de sécurité, veuillez fermer votre "
 | 
					"Central d'Authentification.<br/>Pour des raisons de sécurité, veuillez vous "
 | 
				
			||||||
"navigateur après avoir fini d'accéder a des services demandant une "
 | 
					"déconnecter et fermer votre navigateur après avoir fini d'accéder à des "
 | 
				
			||||||
"authentification !"
 | 
					"services demandant une authentification !"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/cas_server/logged.html:8
 | 
					#: templates/cas_server/logged.html:8
 | 
				
			||||||
msgid "Log me out from all my sessions"
 | 
					msgid "Log me out from all my sessions"
 | 
				
			||||||
@@ -310,7 +321,7 @@ msgstr "Se déconnecter"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#: templates/cas_server/login.html:6
 | 
					#: templates/cas_server/login.html:6
 | 
				
			||||||
msgid "Please log in"
 | 
					msgid "Please log in"
 | 
				
			||||||
msgstr "Merci de se connecter"
 | 
					msgstr "Veuillez vous authentifier"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/cas_server/login.html:14
 | 
					#: templates/cas_server/login.html:14
 | 
				
			||||||
msgid "Login"
 | 
					msgid "Login"
 | 
				
			||||||
@@ -320,7 +331,12 @@ msgstr "Connexion"
 | 
				
			|||||||
msgid "Connect to the service"
 | 
					msgid "Connect to the service"
 | 
				
			||||||
msgstr "Se connecter au service"
 | 
					msgstr "Se connecter au service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:168
 | 
					#: utils.py:736
 | 
				
			||||||
 | 
					#, python-format
 | 
				
			||||||
 | 
					msgid "\"%(value)s\" is not a valid regular expression"
 | 
				
			||||||
 | 
					msgstr "\"%(value)s\" n'est pas une expression rationnelle valide"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: views.py:185
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"<h3>Logout successful</h3>You have successfully logged out from the Central "
 | 
					"<h3>Logout successful</h3>You have successfully logged out from the Central "
 | 
				
			||||||
"Authentication Service. For security reasons, exit your web browser."
 | 
					"Authentication Service. For security reasons, exit your web browser."
 | 
				
			||||||
@@ -329,7 +345,7 @@ msgstr ""
 | 
				
			|||||||
"d'Authentification. Pour des raisons de sécurité, veuillez fermer votre "
 | 
					"d'Authentification. Pour des raisons de sécurité, veuillez fermer votre "
 | 
				
			||||||
"navigateur."
 | 
					"navigateur."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:174
 | 
					#: views.py:191
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"<h3>Logout successful</h3>You have successfully logged out from %s sessions "
 | 
					"<h3>Logout successful</h3>You have successfully logged out from %s sessions "
 | 
				
			||||||
@@ -340,7 +356,7 @@ msgstr ""
 | 
				
			|||||||
"Service Central d'Authentification. Pour des raisons de sécurité, veuillez "
 | 
					"Service Central d'Authentification. Pour des raisons de sécurité, veuillez "
 | 
				
			||||||
"fermer votre navigateur."
 | 
					"fermer votre navigateur."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:181
 | 
					#: views.py:198
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"<h3>Logout successful</h3>You were already logged out from the Central "
 | 
					"<h3>Logout successful</h3>You were already logged out from the Central "
 | 
				
			||||||
"Authentication Service. For security reasons, exit your web browser."
 | 
					"Authentication Service. For security reasons, exit your web browser."
 | 
				
			||||||
@@ -349,7 +365,7 @@ msgstr ""
 | 
				
			|||||||
"d'Authentification. Pour des raisons de sécurité, veuillez fermer votre "
 | 
					"d'Authentification. Pour des raisons de sécurité, veuillez fermer votre "
 | 
				
			||||||
"navigateur."
 | 
					"navigateur."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:361
 | 
					#: views.py:378
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"Invalid response from your identity provider CAS upon ticket %(ticket)s "
 | 
					"Invalid response from your identity provider CAS upon ticket %(ticket)s "
 | 
				
			||||||
@@ -358,48 +374,48 @@ msgstr ""
 | 
				
			|||||||
"Réponse invalide du CAS du fournisseur d'identité lors de la validation du "
 | 
					"Réponse invalide du CAS du fournisseur d'identité lors de la validation du "
 | 
				
			||||||
"ticket %(ticket)s: %(error)r"
 | 
					"ticket %(ticket)s: %(error)r"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:483
 | 
					#: views.py:500
 | 
				
			||||||
msgid "Invalid login ticket, please retry to login"
 | 
					msgid "Invalid login ticket, please retry to login"
 | 
				
			||||||
msgstr "Ticket de connexion invalide, merci de réessayé de vous connecter"
 | 
					msgstr "Ticket de connexion invalide, merci de réessayé de vous connecter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:675
 | 
					#: views.py:692
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid "Authentication has been required by service %(name)s (%(url)s)"
 | 
					msgid "Authentication has been required by service %(name)s (%(url)s)"
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Une demande d'authentification a été émise pour le service %(name)s "
 | 
					"Une demande d'authentification a été émise pour le service %(name)s "
 | 
				
			||||||
"(%(url)s)."
 | 
					"(%(url)s)."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:713
 | 
					#: views.py:730
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid "Service %(url)s non allowed."
 | 
					msgid "Service %(url)s not allowed."
 | 
				
			||||||
msgstr "le service %(url)s n'est pas autorisé."
 | 
					msgstr "le service %(url)s n'est pas autorisé."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:720
 | 
					#: views.py:737
 | 
				
			||||||
msgid "Username non allowed"
 | 
					msgid "Username not allowed"
 | 
				
			||||||
msgstr "Nom d'utilisateur non authorisé"
 | 
					msgstr "Nom d'utilisateur non authorisé"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:727
 | 
					#: views.py:744
 | 
				
			||||||
msgid "User characteristics non allowed"
 | 
					msgid "User characteristics not allowed"
 | 
				
			||||||
msgstr "Caractéristique utilisateur non autorisée"
 | 
					msgstr "Caractéristique utilisateur non autorisée"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:734
 | 
					#: views.py:751
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid "The attribute %(field)s is needed to use that service"
 | 
					msgid "The attribute %(field)s is needed to use that service"
 | 
				
			||||||
msgstr "L'attribut %(field)s est nécessaire pour se connecter à ce service"
 | 
					msgstr "L'attribut %(field)s est nécessaire pour se connecter à ce service"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:824
 | 
					#: views.py:841
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid "Authentication renewal required by service %(name)s (%(url)s)."
 | 
					msgid "Authentication renewal required by service %(name)s (%(url)s)."
 | 
				
			||||||
msgstr "Demande de réauthentification pour le service %(name)s (%(url)s)."
 | 
					msgstr "Demande de réauthentification pour le service %(name)s (%(url)s)."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:831
 | 
					#: views.py:848
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid "Authentication required by service %(name)s (%(url)s)."
 | 
					msgid "Authentication required by service %(name)s (%(url)s)."
 | 
				
			||||||
msgstr "Authentification requise par le service %(name)s (%(url)s)."
 | 
					msgstr "Authentification requise par le service %(name)s (%(url)s)."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views.py:838
 | 
					#: views.py:855
 | 
				
			||||||
#, python-format
 | 
					#, python-format
 | 
				
			||||||
msgid "Service %s non allowed"
 | 
					msgid "Service %s not allowed"
 | 
				
			||||||
msgstr "Le service %s n'est pas autorisé"
 | 
					msgstr "Le service %s n'est pas autorisé"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#~ msgid "Logged"
 | 
					#~ msgid "Logged"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ from ... import models
 | 
				
			|||||||
class Command(BaseCommand):
 | 
					class Command(BaseCommand):
 | 
				
			||||||
    """Clean old trickets"""
 | 
					    """Clean old trickets"""
 | 
				
			||||||
    args = ''
 | 
					    args = ''
 | 
				
			||||||
    help = _(u"Clean old trickets")
 | 
					    help = _(u"Clean old tickets")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle(self, *args, **options):
 | 
					    def handle(self, *args, **options):
 | 
				
			||||||
        models.User.clean_old_entries()
 | 
					        models.User.clean_old_entries()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -466,7 +466,8 @@ class ServicePattern(models.Model):
 | 
				
			|||||||
            "A regular expression matching services. "
 | 
					            "A regular expression matching services. "
 | 
				
			||||||
            "Will usually looks like '^https://some\\.server\\.com/path/.*$'."
 | 
					            "Will usually looks like '^https://some\\.server\\.com/path/.*$'."
 | 
				
			||||||
            "As it is a regular expression, special character must be escaped with a '\\'."
 | 
					            "As it is a regular expression, special character must be escaped with a '\\'."
 | 
				
			||||||
        )
 | 
					        ),
 | 
				
			||||||
 | 
					        validators=[utils.regexpr_validator]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    #: Name of the attribute to transmit as username, if empty the user login is used
 | 
					    #: Name of the attribute to transmit as username, if empty the user login is used
 | 
				
			||||||
    user_field = models.CharField(
 | 
					    user_field = models.CharField(
 | 
				
			||||||
@@ -625,7 +626,7 @@ class ReplaceAttributName(models.Model):
 | 
				
			|||||||
        max_length=255,
 | 
					        max_length=255,
 | 
				
			||||||
        blank=True,
 | 
					        blank=True,
 | 
				
			||||||
        verbose_name=_(u"replace"),
 | 
					        verbose_name=_(u"replace"),
 | 
				
			||||||
        help_text=_(u"name under which the attribute will be show"
 | 
					        help_text=_(u"name under which the attribute will be show "
 | 
				
			||||||
                    u"to the service. empty = default name of the attribut")
 | 
					                    u"to the service. empty = default name of the attribut")
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    #: ForeignKey to a :class:`ServicePattern`. :class:`ReplaceAttributName` instances for a
 | 
					    #: ForeignKey to a :class:`ServicePattern`. :class:`ReplaceAttributName` instances for a
 | 
				
			||||||
@@ -660,7 +661,8 @@ class FilterAttributValue(models.Model):
 | 
				
			|||||||
    pattern = models.CharField(
 | 
					    pattern = models.CharField(
 | 
				
			||||||
        max_length=255,
 | 
					        max_length=255,
 | 
				
			||||||
        verbose_name=_(u"pattern"),
 | 
					        verbose_name=_(u"pattern"),
 | 
				
			||||||
        help_text=_(u"a regular expression")
 | 
					        help_text=_(u"a regular expression"),
 | 
				
			||||||
 | 
					        validators=[utils.regexpr_validator]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    #: ForeignKey to a :class:`ServicePattern`. :class:`FilterAttributValue` instances for a
 | 
					    #: ForeignKey to a :class:`ServicePattern`. :class:`FilterAttributValue` instances for a
 | 
				
			||||||
    #: :class:`ServicePattern` are accessible thought its :attr:`ServicePattern.filters`
 | 
					    #: :class:`ServicePattern` are accessible thought its :attr:`ServicePattern.filters`
 | 
				
			||||||
@@ -689,7 +691,8 @@ class ReplaceAttributValue(models.Model):
 | 
				
			|||||||
    pattern = models.CharField(
 | 
					    pattern = models.CharField(
 | 
				
			||||||
        max_length=255,
 | 
					        max_length=255,
 | 
				
			||||||
        verbose_name=_(u"pattern"),
 | 
					        verbose_name=_(u"pattern"),
 | 
				
			||||||
        help_text=_(u"An regular expression maching whats need to be replaced")
 | 
					        help_text=_(u"An regular expression maching whats need to be replaced"),
 | 
				
			||||||
 | 
					        validators=[utils.regexpr_validator]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    #: The replacement to what is mached by :attr:`pattern`. groups are capture by \\1, \\2 …
 | 
					    #: The replacement to what is mached by :attr:`pattern`. groups are capture by \\1, \\2 …
 | 
				
			||||||
    replace = models.CharField(
 | 
					    replace = models.CharField(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,14 +31,14 @@ function eraseCookie(name) {
 | 
				
			|||||||
    createCookie(name,"",-1);
 | 
					    createCookie(name,"",-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function alert_version(last_version){
 | 
					function discard_and_remember(id, cookie_name, token, days=10*365){
 | 
				
			||||||
    jQuery(function( $ ){
 | 
					    jQuery(function( $ ){
 | 
				
			||||||
        $("#alert-version").click(function( e ){
 | 
					        $(id).click(function( e ){
 | 
				
			||||||
            e.preventDefault();
 | 
					            e.preventDefault();
 | 
				
			||||||
            createCookie("cas-alert-version", last_version, 10*365);
 | 
					            createCookie(cookie_name, token, days);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        if(readCookie("cas-alert-version") === last_version){
 | 
					        if(readCookie(cookie_name) === token){
 | 
				
			||||||
            $("#alert-version").parent().hide();
 | 
					            $(id).parent().hide();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,10 +31,16 @@
 | 
				
			|||||||
            <div class="col-lg-3 col-md-3 col-sm-2 col-xs-12"></div>
 | 
					            <div class="col-lg-3 col-md-3 col-sm-2 col-xs-12"></div>
 | 
				
			||||||
            <div class="col-lg-6 col-md-6 col-sm-8 col-xs-12">
 | 
					            <div class="col-lg-6 col-md-6 col-sm-8 col-xs-12">
 | 
				
			||||||
            {% if auto_submit %}<noscript>{% endif %}
 | 
					            {% if auto_submit %}<noscript>{% endif %}
 | 
				
			||||||
 | 
					            {% for msg in CAS_INFO_RENDER %}
 | 
				
			||||||
 | 
					              <div class="alert alert-{{msg.type}}{% if msg.discardable %} alert-dismissable{% endif %}">
 | 
				
			||||||
 | 
					                {% if msg.discardable %}<button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="info-{{msg.name}}">×</button>{% endif %}
 | 
				
			||||||
 | 
					                <p>{{msg.message}}</p>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
            {% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
 | 
					            {% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
 | 
				
			||||||
              <div class="alert alert-info alert-dismissable">
 | 
					              <div class="alert alert-info alert-dismissable">
 | 
				
			||||||
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="alert-version">×</button>
 | 
					                <button type="button" class="close" data-dismiss="alert" aria-hidden="true" id="alert-version">×</button>
 | 
				
			||||||
                {% blocktrans %}A new version of the application is available. This instance runs {{VERSION}} and the last version is {{LAST_VERSION}}. Please consider upgrading.{% endblocktrans %}
 | 
					                <p>{% blocktrans %}A new version of the application is available. This instance runs {{VERSION}} and the last version is {{LAST_VERSION}}. Please consider upgrading.{% endblocktrans %}</p>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
            {% block ante_messages %}{% endblock %}
 | 
					            {% block ante_messages %}{% endblock %}
 | 
				
			||||||
@@ -52,7 +58,7 @@
 | 
				
			|||||||
                        class="alert alert-danger"
 | 
					                        class="alert alert-danger"
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                {% endspaceless %}>
 | 
					                {% endspaceless %}>
 | 
				
			||||||
                    {{message|safe}}
 | 
					                    <p>{{message|safe}}</p>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            {% endfor %}
 | 
					            {% endfor %}
 | 
				
			||||||
            {% if auto_submit %}</noscript>{% endif %}
 | 
					            {% if auto_submit %}</noscript>{% endif %}
 | 
				
			||||||
@@ -71,9 +77,17 @@
 | 
				
			|||||||
      <script src="{{settings.CAS_COMPONENT_URLS.jquery}}"></script>
 | 
					      <script src="{{settings.CAS_COMPONENT_URLS.jquery}}"></script>
 | 
				
			||||||
      <script src="{{settings.CAS_COMPONENT_URLS.bootstrap3_js}}"></script>
 | 
					      <script src="{{settings.CAS_COMPONENT_URLS.bootstrap3_js}}"></script>
 | 
				
			||||||
      <script src="{% static "cas_server/functions.js" %}"></script>
 | 
					      <script src="{% static "cas_server/functions.js" %}"></script>
 | 
				
			||||||
      {% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
 | 
					      <script type="text/javascript">
 | 
				
			||||||
      <script type="text/javascript">alert_version("{{LAST_VERSION}}")</script>
 | 
					{% if settings.CAS_NEW_VERSION_HTML_WARNING and upgrade_available %}
 | 
				
			||||||
      {% endif %}
 | 
					discard_and_remember("#alert-version", "cas-alert-version", "{{LAST_VERSION}}");
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% for msg in CAS_INFO_RENDER %}
 | 
				
			||||||
 | 
					{% if msg.discardable %}
 | 
				
			||||||
 | 
					discard_and_remember("#info-{{msg.name}}", "cas-info-{{msg.name}}", "{{msg.hash}}");
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% endfor %}
 | 
				
			||||||
 | 
					{% block javascript_inline %}{% endblock %}
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
      {% block javascript %}{% endblock %}
 | 
					      {% block javascript %}{% endblock %}
 | 
				
			||||||
    </body>
 | 
					    </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@
 | 
				
			|||||||
  {% if auto_submit %}</noscript>{% endif %}
 | 
					  {% if auto_submit %}</noscript>{% endif %}
 | 
				
			||||||
</form>
 | 
					</form>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
{% block javascript %}<script type="text/javascript">
 | 
					{% block javascript_inline %}
 | 
				
			||||||
jQuery(function( $ ){
 | 
					jQuery(function( $ ){
 | 
				
			||||||
    $("#id_warn").click(function(e){
 | 
					    $("#id_warn").click(function(e){
 | 
				
			||||||
        if($("#id_warn").is(':checked')){
 | 
					        if($("#id_warn").is(':checked')){
 | 
				
			||||||
@@ -26,5 +26,5 @@ jQuery(function( $ ){
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
});{% if auto_submit %}
 | 
					});{% if auto_submit %}
 | 
				
			||||||
document.getElementById('login_form').submit(); // SUBMIT FORM{% endif %}
 | 
					document.getElementById('login_form').submit(); // SUBMIT FORM{% endif %}
 | 
				
			||||||
</script>{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -255,3 +255,9 @@ class UtilsTestCase(TestCase):
 | 
				
			|||||||
                self.assertIsInstance(result, dict)
 | 
					                self.assertIsInstance(result, dict)
 | 
				
			||||||
                self.assertIn('applied', result)
 | 
					                self.assertIn('applied', result)
 | 
				
			||||||
                self.assertIsInstance(result['applied'], datetime.datetime)
 | 
					                self.assertIsInstance(result['applied'], datetime.datetime)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_regexpr_validator(self):
 | 
				
			||||||
 | 
					        """test the function regexpr_validator"""
 | 
				
			||||||
 | 
					        utils.regexpr_validator("^a$")
 | 
				
			||||||
 | 
					        with self.assertRaises(utils.ValidationError):
 | 
				
			||||||
 | 
					            utils.regexpr_validator("[")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,6 +75,45 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
 | 
				
			|||||||
        response = client.get("/login")
 | 
					        response = client.get("/login")
 | 
				
			||||||
        self.assertNotIn(b"A new version of the application is available", response.content)
 | 
					        self.assertNotIn(b"A new version of the application is available", response.content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @override_settings(CAS_INFO_MESSAGES_ORDER=["cas_explained"])
 | 
				
			||||||
 | 
					    def test_messages_info_box_enabled(self):
 | 
				
			||||||
 | 
					        """test that the message info-box is displayed then enabled"""
 | 
				
			||||||
 | 
					        client = Client()
 | 
				
			||||||
 | 
					        response = client.get("/login")
 | 
				
			||||||
 | 
					        self.assertIn(
 | 
				
			||||||
 | 
					            b"The Central Authentication Service grants you access to most of our websites by ",
 | 
				
			||||||
 | 
					            response.content
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @override_settings(CAS_INFO_MESSAGES_ORDER=[])
 | 
				
			||||||
 | 
					    def test_messages_info_box_disabled(self):
 | 
				
			||||||
 | 
					        """test that the message info-box is not displayed then disabled"""
 | 
				
			||||||
 | 
					        client = Client()
 | 
				
			||||||
 | 
					        response = client.get("/login")
 | 
				
			||||||
 | 
					        self.assertNotIn(
 | 
				
			||||||
 | 
					            b"The Central Authentication Service grants you access to most of our websites by ",
 | 
				
			||||||
 | 
					            response.content
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # test1 and test2 are malformed and should be ignored, test3 is ok, test5 do not
 | 
				
			||||||
 | 
					    # exists and should be ignored
 | 
				
			||||||
 | 
					    @override_settings(CAS_INFO_MESSAGES_ORDER=["test1", "test2", "test3", "test5"])
 | 
				
			||||||
 | 
					    @override_settings(CAS_INFO_MESSAGES={
 | 
				
			||||||
 | 
					        "test1": "test",  # not a dict, should be ignored
 | 
				
			||||||
 | 
					        "test2": {"type": "success"},  # not "message" key, should be ignored
 | 
				
			||||||
 | 
					        "test3": {"message": "test3"},
 | 
				
			||||||
 | 
					        "test4": {"message": "test4"},
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    def test_messages_info_box_bad_messages(self):
 | 
				
			||||||
 | 
					        """test that mal formated messages dict are ignored"""
 | 
				
			||||||
 | 
					        client = Client()
 | 
				
			||||||
 | 
					        # not errors should be raises
 | 
				
			||||||
 | 
					        response = client.get("/login")
 | 
				
			||||||
 | 
					        # test3 is ok est should be there
 | 
				
			||||||
 | 
					        self.assertIn(b"test3", response.content)
 | 
				
			||||||
 | 
					        # test4 is not in CAS_INFO_MESSAGES_ORDER and should not be there
 | 
				
			||||||
 | 
					        self.assertNotIn(b"test4", response.content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_login_view_post_goodpass_goodlt(self):
 | 
					    def test_login_view_post_goodpass_goodlt(self):
 | 
				
			||||||
        """Test a successul login"""
 | 
					        """Test a successul login"""
 | 
				
			||||||
        # we get a client who fetch a frist time the login page and the login form default
 | 
					        # we get a client who fetch a frist time the login page and the login form default
 | 
				
			||||||
@@ -234,7 +273,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
 | 
				
			|||||||
        response = client.get("/login?service=https://www.example.net")
 | 
					        response = client.get("/login?service=https://www.example.net")
 | 
				
			||||||
        self.assertEqual(response.status_code, 200)
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
        # we warn the user that https://www.example.net is not an allowed service url
 | 
					        # we warn the user that https://www.example.net is not an allowed service url
 | 
				
			||||||
        self.assertTrue(b"Service https://www.example.net non allowed" in response.content)
 | 
					        self.assertTrue(b"Service https://www.example.net not allowed" in response.content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_view_login_get_auth_allowed_service(self):
 | 
					    def test_view_login_get_auth_allowed_service(self):
 | 
				
			||||||
        """Request a ticket for an allowed service by an authenticated client"""
 | 
					        """Request a ticket for an allowed service by an authenticated client"""
 | 
				
			||||||
@@ -280,7 +319,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
 | 
				
			|||||||
        self.assertEqual(response.status_code, 200)
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
        # we warn the user that https://www.example.net is not an allowed service url
 | 
					        # we warn the user that https://www.example.net is not an allowed service url
 | 
				
			||||||
        # NO ticket are created
 | 
					        # NO ticket are created
 | 
				
			||||||
        self.assertTrue(b"Service https://www.example.org non allowed" in response.content)
 | 
					        self.assertTrue(b"Service https://www.example.org not allowed" in response.content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_user_logged_not_in_db(self):
 | 
					    def test_user_logged_not_in_db(self):
 | 
				
			||||||
        """If the user is logged but has been delete from the database, it should be logged out"""
 | 
					        """If the user is logged but has been delete from the database, it should be logged out"""
 | 
				
			||||||
@@ -314,7 +353,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
 | 
				
			|||||||
        response = client.get("/login", {'service': self.service_restrict_user_fail})
 | 
					        response = client.get("/login", {'service': self.service_restrict_user_fail})
 | 
				
			||||||
        self.assertEqual(response.status_code, 200)
 | 
					        self.assertEqual(response.status_code, 200)
 | 
				
			||||||
        # the ticket is not created and a warning is displayed to the user
 | 
					        # the ticket is not created and a warning is displayed to the user
 | 
				
			||||||
        self.assertTrue(b"Username non allowed" in response.content)
 | 
					        self.assertTrue(b"Username not allowed" in response.content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # same but with the tes user username being one of the allowed usernames
 | 
					        # same but with the tes user username being one of the allowed usernames
 | 
				
			||||||
        response = client.get("/login", {'service': self.service_restrict_user_success})
 | 
					        response = client.get("/login", {'service': self.service_restrict_user_success})
 | 
				
			||||||
@@ -337,7 +376,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
 | 
				
			|||||||
            response = client.get("/login", {'service': service})
 | 
					            response = client.get("/login", {'service': service})
 | 
				
			||||||
            # the ticket is not created and a warning is displayed to the user
 | 
					            # the ticket is not created and a warning is displayed to the user
 | 
				
			||||||
            self.assertEqual(response.status_code, 200)
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
            self.assertTrue(b"User characteristics non allowed" in response.content)
 | 
					            self.assertTrue(b"User characteristics not allowed" in response.content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # same but with rectriction that a valid upon the test user attributes
 | 
					        # same but with rectriction that a valid upon the test user attributes
 | 
				
			||||||
        response = client.get("/login", {'service': self.service_filter_success})
 | 
					        response = client.get("/login", {'service': self.service_filter_success})
 | 
				
			||||||
@@ -546,7 +585,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
 | 
				
			|||||||
        self.assertEqual(data["messages"][0]["level"], "error")
 | 
					        self.assertEqual(data["messages"][0]["level"], "error")
 | 
				
			||||||
        self.assertEqual(
 | 
					        self.assertEqual(
 | 
				
			||||||
            data["messages"][0]["message"],
 | 
					            data["messages"][0]["message"],
 | 
				
			||||||
            "Service https://www.example.org non allowed."
 | 
					            "Service https://www.example.org not allowed."
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @override_settings(CAS_ENABLE_AJAX_AUTH=True)
 | 
					    @override_settings(CAS_ENABLE_AJAX_AUTH=True)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,10 @@ from django.contrib import messages
 | 
				
			|||||||
from django.contrib.messages import constants as DEFAULT_MESSAGE_LEVELS
 | 
					from django.contrib.messages import constants as DEFAULT_MESSAGE_LEVELS
 | 
				
			||||||
from django.core.serializers.json import DjangoJSONEncoder
 | 
					from django.core.serializers.json import DjangoJSONEncoder
 | 
				
			||||||
from django.utils import timezone
 | 
					from django.utils import timezone
 | 
				
			||||||
 | 
					from django.core.exceptions import ValidationError
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
import string
 | 
					import string
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
@@ -61,6 +64,7 @@ def context(params):
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
    params["settings"] = settings
 | 
					    params["settings"] = settings
 | 
				
			||||||
    params["message_levels"] = DEFAULT_MESSAGE_LEVELS
 | 
					    params["message_levels"] = DEFAULT_MESSAGE_LEVELS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if settings.CAS_NEW_VERSION_HTML_WARNING:
 | 
					    if settings.CAS_NEW_VERSION_HTML_WARNING:
 | 
				
			||||||
        LAST_VERSION = last_version()
 | 
					        LAST_VERSION = last_version()
 | 
				
			||||||
        params["VERSION"] = VERSION
 | 
					        params["VERSION"] = VERSION
 | 
				
			||||||
@@ -69,6 +73,27 @@ def context(params):
 | 
				
			|||||||
            params["upgrade_available"] = decode_version(VERSION) < decode_version(LAST_VERSION)
 | 
					            params["upgrade_available"] = decode_version(VERSION) < decode_version(LAST_VERSION)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            params["upgrade_available"] = False
 | 
					            params["upgrade_available"] = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if settings.CAS_INFO_MESSAGES_ORDER:
 | 
				
			||||||
 | 
					        params["CAS_INFO_RENDER"] = []
 | 
				
			||||||
 | 
					        for msg_name in settings.CAS_INFO_MESSAGES_ORDER:
 | 
				
			||||||
 | 
					            if msg_name in settings.CAS_INFO_MESSAGES:
 | 
				
			||||||
 | 
					                if not isinstance(settings.CAS_INFO_MESSAGES[msg_name], dict):
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                msg = settings.CAS_INFO_MESSAGES[msg_name].copy()
 | 
				
			||||||
 | 
					                if "message" in msg:
 | 
				
			||||||
 | 
					                    msg["name"] = msg_name
 | 
				
			||||||
 | 
					                    # use info as default infox type
 | 
				
			||||||
 | 
					                    msg["type"] = msg.get("type", "info")
 | 
				
			||||||
 | 
					                    # make box discardable by default
 | 
				
			||||||
 | 
					                    msg["discardable"] = msg.get("discardable", True)
 | 
				
			||||||
 | 
					                    msg_hash = (
 | 
				
			||||||
 | 
					                        six.text_type(msg["message"]).encode("utf-8") +
 | 
				
			||||||
 | 
					                        msg["type"].encode("utf-8")
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    # hash depend of the rendering language
 | 
				
			||||||
 | 
					                    msg["hash"] = hashlib.md5(msg_hash).hexdigest()
 | 
				
			||||||
 | 
					                    params["CAS_INFO_RENDER"].append(msg)
 | 
				
			||||||
    return params
 | 
					    return params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -700,3 +725,19 @@ def logout_request(ticket):
 | 
				
			|||||||
        'datetime': timezone.now().isoformat(),
 | 
					        'datetime': timezone.now().isoformat(),
 | 
				
			||||||
        'ticket':  ticket
 | 
					        'ticket':  ticket
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def regexpr_validator(value):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					        Test that ``value`` is a valid regular expression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param unicode value: A regular expression to test
 | 
				
			||||||
 | 
					        :raises ValidationError: if ``value`` is not a valid regular expression
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        re.compile(value)
 | 
				
			||||||
 | 
					    except re.error:
 | 
				
			||||||
 | 
					        raise ValidationError(
 | 
				
			||||||
 | 
					            _('"%(value)s" is not a valid regular expression'),
 | 
				
			||||||
 | 
					            params={'value': value}
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -727,21 +727,21 @@ class LoginView(View, LogoutMixin):
 | 
				
			|||||||
            messages.add_message(
 | 
					            messages.add_message(
 | 
				
			||||||
                self.request,
 | 
					                self.request,
 | 
				
			||||||
                messages.ERROR,
 | 
					                messages.ERROR,
 | 
				
			||||||
                _(u'Service %(url)s non allowed.') % {'url': self.service}
 | 
					                _(u'Service %(url)s not allowed.') % {'url': self.service}
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        except models.BadUsername:
 | 
					        except models.BadUsername:
 | 
				
			||||||
            error = 2
 | 
					            error = 2
 | 
				
			||||||
            messages.add_message(
 | 
					            messages.add_message(
 | 
				
			||||||
                self.request,
 | 
					                self.request,
 | 
				
			||||||
                messages.ERROR,
 | 
					                messages.ERROR,
 | 
				
			||||||
                _(u"Username non allowed")
 | 
					                _(u"Username not allowed")
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        except models.BadFilter:
 | 
					        except models.BadFilter:
 | 
				
			||||||
            error = 3
 | 
					            error = 3
 | 
				
			||||||
            messages.add_message(
 | 
					            messages.add_message(
 | 
				
			||||||
                self.request,
 | 
					                self.request,
 | 
				
			||||||
                messages.ERROR,
 | 
					                messages.ERROR,
 | 
				
			||||||
                _(u"User characteristics non allowed")
 | 
					                _(u"User characteristics not allowed")
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        except models.UserFieldNotDefined:
 | 
					        except models.UserFieldNotDefined:
 | 
				
			||||||
            error = 4
 | 
					            error = 4
 | 
				
			||||||
@@ -852,7 +852,7 @@ class LoginView(View, LogoutMixin):
 | 
				
			|||||||
                messages.add_message(
 | 
					                messages.add_message(
 | 
				
			||||||
                    self.request,
 | 
					                    self.request,
 | 
				
			||||||
                    messages.ERROR,
 | 
					                    messages.ERROR,
 | 
				
			||||||
                    _(u'Service %s non allowed') % self.service
 | 
					                    _(u'Service %s not allowed') % self.service
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
        if self.ajax:
 | 
					        if self.ajax:
 | 
				
			||||||
            data = {
 | 
					            data = {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								docs/CHANGELOG.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/CHANGELOG.rst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					.. include:: ../CHANGELOG.rst
 | 
				
			||||||
@@ -14,6 +14,11 @@ Contents:
 | 
				
			|||||||
   README
 | 
					   README
 | 
				
			||||||
   package/cas_server
 | 
					   package/cas_server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. toctree::
 | 
				
			||||||
 | 
					   :maxdepth: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   CHANGELOG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Indices and tables
 | 
					Indices and tables
 | 
				
			||||||
==================
 | 
					==================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tox.ini
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tox.ini
									
									
									
									
									
								
							@@ -101,6 +101,7 @@ deps=
 | 
				
			|||||||
skip_install=True
 | 
					skip_install=True
 | 
				
			||||||
commands=
 | 
					commands=
 | 
				
			||||||
    rst2html.py --strict {toxinidir}/README.rst /dev/null
 | 
					    rst2html.py --strict {toxinidir}/README.rst /dev/null
 | 
				
			||||||
 | 
					    rst2html.py --halt=warning {toxinidir}/CHANGELOG.rst /dev/null
 | 
				
			||||||
    {[post_cmd]commands}
 | 
					    {[post_cmd]commands}
 | 
				
			||||||
whitelist_externals={[post_cmd]whitelist_externals}
 | 
					whitelist_externals={[post_cmd]whitelist_externals}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user