Commit 502135d6 authored by Valentin Samir's avatar Valentin Samir

Fix bug: the renewing authentication, it is ok for the service to not require renew

parent abf0200f
...@@ -595,6 +595,12 @@ class Ticket(models.Model): ...@@ -595,6 +595,12 @@ class Ticket(models.Model):
) )
) )
@staticmethod
def get_class(ticket):
for ticket_class in [ServiceTicket, ProxyTicket, ProxyGrantingTicket]:
if ticket.startswith(ticket_class.PREFIX):
return ticket_class
@python_2_unicode_compatible @python_2_unicode_compatible
class ServiceTicket(Ticket): class ServiceTicket(Ticket):
......
...@@ -990,6 +990,52 @@ class ValidateTestCase(TestCase): ...@@ -990,6 +990,52 @@ class ValidateTestCase(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, b'yes\ntest\n') self.assertEqual(response.content, b'yes\ntest\n')
def test_validate_service_renew(self):
"""test with a valid (ticket, service) asking for auth renewal"""
# case 1 client is renewing and service ask for renew
(client1, response) = get_auth_client(renew="True", service=self.service)
self.assertEqual(response.status_code, 302)
ticket_value = response['Location'].split('ticket=')[-1]
# get a bare client
client = Client()
# requesting validation with a good (ticket, service)
response = client.get(
'/validate',
{'ticket': ticket_value, 'service': self.service, 'renew': 'True'}
)
# the validation should succes with username settings.CAS_TEST_USER and transmit
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, b'yes\ntest\n')
# cas2 client is renewing and service do not ask for renew
(client2, response) = get_auth_client(renew="True", service=self.service)
self.assertEqual(response.status_code, 302)
ticket_value = response['Location'].split('ticket=')[-1]
# get a bare client
client = Client()
# requesting validation with a good (ticket, service)
response = client.get(
'/validate',
{'ticket': ticket_value, 'service': self.service}
)
# the validation should succes with username settings.CAS_TEST_USER and transmit
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, b'yes\ntest\n')
# case 3, client is not renewing and service ask for renew (client is authenticated)
response = client2.get("/login", {"service": self.service})
self.assertEqual(response.status_code, 302)
ticket_value = response['Location'].split('ticket=')[-1]
client = Client()
# requesting validation with a good (ticket, service)
response = client.get(
'/validate',
{'ticket': ticket_value, 'service': self.service, 'renew': 'True'}
)
# the validation should fail
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, b'no\n')
def test_validate_view_badservice(self): def test_validate_view_badservice(self):
"""test for a valid ticket but bad service""" """test for a valid ticket but bad service"""
ticket = get_user_ticket_request(self.service)[1] ticket = get_user_ticket_request(self.service)[1]
...@@ -1144,6 +1190,55 @@ class ValidateServiceTestCase(TestCase, XmlContent): ...@@ -1144,6 +1190,55 @@ class ValidateServiceTestCase(TestCase, XmlContent):
# the attributes settings.CAS_TEST_ATTRIBUTES # the attributes settings.CAS_TEST_ATTRIBUTES
self.assert_success(response, settings.CAS_TEST_USER, settings.CAS_TEST_ATTRIBUTES) self.assert_success(response, settings.CAS_TEST_USER, settings.CAS_TEST_ATTRIBUTES)
def test_validate_service_renew(self):
"""test with a valid (ticket, service) asking for auth renewal"""
# case 1 client is renewing and service ask for renew
(client1, response) = get_auth_client(renew="True", service=self.service)
self.assertEqual(response.status_code, 302)
ticket_value = response['Location'].split('ticket=')[-1]
# get a bare client
client = Client()
# requesting validation with a good (ticket, service)
response = client.get(
'/serviceValidate',
{'ticket': ticket_value, 'service': self.service, 'renew': 'True'}
)
# the validation should succes with username settings.CAS_TEST_USER and transmit
# the attributes settings.CAS_TEST_ATTRIBUTES
self.assert_success(response, settings.CAS_TEST_USER, settings.CAS_TEST_ATTRIBUTES)
# cas2 client is renewing and service do not ask for renew
(client2, response) = get_auth_client(renew="True", service=self.service)
self.assertEqual(response.status_code, 302)
ticket_value = response['Location'].split('ticket=')[-1]
# get a bare client
client = Client()
# requesting validation with a good (ticket, service)
response = client.get(
'/serviceValidate',
{'ticket': ticket_value, 'service': self.service}
)
# the validation should succes with username settings.CAS_TEST_USER and transmit
# the attributes settings.CAS_TEST_ATTRIBUTES
self.assert_success(response, settings.CAS_TEST_USER, settings.CAS_TEST_ATTRIBUTES)
# case 3, client is not renewing and service ask for renew (client is authenticated)
response = client2.get("/login", {"service": self.service})
self.assertEqual(response.status_code, 302)
ticket_value = response['Location'].split('ticket=')[-1]
client = Client()
# requesting validation with a good (ticket, service)
response = client.get(
'/serviceValidate',
{'ticket': ticket_value, 'service': self.service, 'renew': 'True'}
)
# the validation should fail
self.assert_error(
response,
"INVALID_TICKET",
'ticket not found'
)
def test_validate_service_view_ok_one_attribute(self): def test_validate_service_view_ok_one_attribute(self):
""" """
test with a valid (ticket, service), the username and test with a valid (ticket, service), the username and
......
...@@ -74,9 +74,12 @@ def get_auth_client(**update): ...@@ -74,9 +74,12 @@ def get_auth_client(**update):
params["password"] = settings.CAS_TEST_PASSWORD params["password"] = settings.CAS_TEST_PASSWORD
params.update(update) params.update(update)
client.post('/login', params) response = client.post('/login', params)
assert client.session.get("authenticated") assert client.session.get("authenticated")
if params.get("service"):
return (client, response)
else:
return client return client
......
...@@ -751,13 +751,16 @@ class Validate(View): ...@@ -751,13 +751,16 @@ class Validate(View):
renew = True if request.GET.get('renew') else False renew = True if request.GET.get('renew') else False
if service and ticket: if service and ticket:
try: try:
ticket = ServiceTicket.objects.get( ticket_queryset = ServiceTicket.objects.filter(
value=ticket, value=ticket,
service=service, service=service,
validate=False, validate=False,
renew=renew,
creation__gt=(timezone.now() - timedelta(seconds=ServiceTicket.VALIDITY)) creation__gt=(timezone.now() - timedelta(seconds=ServiceTicket.VALIDITY))
) )
if renew:
ticket = ticket_queryset.get(renew=True)
else:
ticket = ticket_queryset.get()
ticket.validate = True ticket.validate = True
ticket.save() ticket.save()
logger.info( logger.info(
...@@ -893,20 +896,18 @@ class ValidateService(View, AttributesMixin): ...@@ -893,20 +896,18 @@ class ValidateService(View, AttributesMixin):
"""fetch the ticket angains the database and check its validity""" """fetch the ticket angains the database and check its validity"""
try: try:
proxies = [] proxies = []
if self.ticket.startswith(ServiceTicket.PREFIX): ticket_class = models.Ticket.get_class(self.ticket)
ticket = ServiceTicket.objects.get( if ticket_class:
ticket_queryset = ticket_class.objects.filter(
value=self.ticket, value=self.ticket,
validate=False, validate=False,
renew=self.renew,
creation__gt=(timezone.now() - timedelta(seconds=ServiceTicket.VALIDITY)) creation__gt=(timezone.now() - timedelta(seconds=ServiceTicket.VALIDITY))
) )
elif self.allow_proxy_ticket and self.ticket.startswith(ProxyTicket.PREFIX): if self.renew:
ticket = ProxyTicket.objects.get( ticket = ticket_queryset.get(renew=True)
value=self.ticket, else:
validate=False, ticket = ticket_queryset.get()
renew=self.renew, if ticket_class == models.ProxyTicket:
creation__gt=(timezone.now() - timedelta(seconds=ProxyTicket.VALIDITY))
)
for prox in ticket.proxies.all(): for prox in ticket.proxies.all():
proxies.append(prox.url) proxies.append(prox.url)
else: else:
...@@ -1140,18 +1141,13 @@ class SamlValidate(View, AttributesMixin): ...@@ -1140,18 +1141,13 @@ class SamlValidate(View, AttributesMixin):
try: try:
auth_req = self.root.getchildren()[1].getchildren()[0] auth_req = self.root.getchildren()[1].getchildren()[0]
ticket = auth_req.getchildren()[0].text ticket = auth_req.getchildren()[0].text
if ticket.startswith(ServiceTicket.PREFIX): ticket_class = models.Ticket.get_class(ticket)
ticket = ServiceTicket.objects.get( if ticket_class:
ticket = ticket_class.objects.get(
value=ticket, value=ticket,
validate=False, validate=False,
creation__gt=(timezone.now() - timedelta(seconds=ServiceTicket.VALIDITY)) creation__gt=(timezone.now() - timedelta(seconds=ServiceTicket.VALIDITY))
) )
elif ticket.startswith(ProxyTicket.PREFIX):
ticket = ProxyTicket.objects.get(
value=ticket,
validate=False,
creation__gt=(timezone.now() - timedelta(seconds=ProxyTicket.VALIDITY))
)
else: else:
raise SamlValidateError( raise SamlValidateError(
u'AuthnFailed', u'AuthnFailed',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment