1
1
import logging
2
- from types import SimpleNamespace
2
+ import os
3
+ import stat
3
4
4
5
import pytest
5
6
from flask import Flask , g
6
7
from gssapi .raw .exceptions import ExpiredCredentialsError
7
- from werkzeug .exceptions import Forbidden , InternalServerError , Unauthorized
8
+ from werkzeug .exceptions import Forbidden , InternalServerError
8
9
9
10
from flask_mod_auth_gssapi import FlaskModAuthGSSAPI
10
11
@@ -45,29 +46,17 @@ def test_no_cache(app, wsgi_env):
45
46
assert g .username is None
46
47
47
48
48
- def test_expired (app , wsgi_env , caplog , mocker ):
49
- creds_factory = mocker .patch ("gssapi.Credentials" )
50
- creds_factory .return_value = SimpleNamespace (lifetime = 0 )
49
+ def test_expired (app , wsgi_env , caplog , expired_credential , tmp_path ):
50
+ ccache_path = tmp_path .joinpath ("ccache" )
51
+ open (ccache_path , "w" ).close () # Create the file
52
+ wsgi_env ["KRB5CCNAME" ] = f"FILE:{ ccache_path .as_posix ()} "
51
53
caplog .set_level (logging .INFO )
52
54
client = app .test_client ()
53
55
response = client .get ("/someplace" , environ_base = wsgi_env )
54
- assert response .status_code == 302
55
- assert response .headers ["location " ] == "http://localhost/someplace "
56
+ assert response .status_code == 401
57
+ assert response .headers ["www-authenticate " ] == "Negotiate "
56
58
assert caplog .messages == ["Credential lifetime has expired." ]
57
-
58
-
59
- def test_expired_unsafe_method (app , wsgi_env , mocker ):
60
- creds_factory = mocker .patch ("gssapi.Credentials" )
61
- creds_factory .return_value = SimpleNamespace (lifetime = 0 )
62
- with app .test_request_context ("/someplace" , method = "POST" , environ_base = wsgi_env ):
63
- with pytest .raises (Unauthorized ) as excinfo :
64
- app .preprocess_request ()
65
- assert g .principal is None
66
- assert g .username is None
67
- assert (
68
- excinfo .value .description
69
- == "Re-authentication is necessary, please try your request again."
70
- )
59
+ assert not os .path .exists (ccache_path )
71
60
72
61
73
62
def test_expired_exception (app , wsgi_env , mocker , caplog ):
@@ -85,14 +74,29 @@ def lifetime(self):
85
74
response = client .get ("/someplace" , environ_base = wsgi_env )
86
75
except ExpiredCredentialsError :
87
76
pytest .fail ("Did not catch ExpiredCredentialsError on cred.lifetime" )
88
- assert response .status_code == 302
89
- assert response .headers ["location " ] == "http://localhost/someplace "
77
+ assert response .status_code == 401
78
+ assert response .headers ["www-authenticate " ] == "Negotiate "
90
79
assert caplog .messages == ["Credential lifetime has expired." ]
91
80
92
81
93
- def test_nominal (app , wsgi_env , mocker ):
94
- creds_factory = mocker .patch ("gssapi.Credentials" )
95
- creds_factory .return_value = SimpleNamespace (lifetime = 10 )
82
+ def test_expired_cant_remove (app , wsgi_env , caplog , expired_credential , tmp_path ):
83
+ ccaches_dir = tmp_path .joinpath ("ccaches" )
84
+ os .makedirs (ccaches_dir )
85
+ ccache_path = ccaches_dir .joinpath ("ccache" )
86
+ open (ccache_path , "w" ).close () # Create the file
87
+ os .chmod (ccaches_dir , stat .S_IRUSR | stat .S_IXUSR ) # Prevent writing to this dir
88
+ wsgi_env ["KRB5CCNAME" ] = f"FILE:{ ccache_path .as_posix ()} "
89
+ client = app .test_client ()
90
+ response = client .get ("/someplace" , environ_base = wsgi_env )
91
+ assert response .status_code == 401
92
+ assert response .headers ["www-authenticate" ] == "Negotiate"
93
+ assert caplog .messages == [
94
+ f"Could not remove expired credential at { ccache_path .as_posix ()} : "
95
+ f"[Errno 13] Permission denied: '{ ccache_path .as_posix ()} '"
96
+ ]
97
+
98
+
99
+ def test_nominal (app , wsgi_env , credential ):
96
100
with app .test_request_context ("/" , environ_base = wsgi_env ):
97
101
app .preprocess_request ()
98
102
assert g .
principal == "[email protected] "
@@ -122,6 +126,6 @@ def test_ccache_not_found(app, wsgi_env, caplog, mocker):
122
126
# caplog.set_level(logging.INFO)
123
127
client = app .test_client ()
124
128
response = client .get ("/someplace" , environ_base = wsgi_env )
125
- assert response .status_code == 302
126
- assert response .headers ["location " ] == "http://localhost/someplace "
129
+ assert response .status_code == 401
130
+ assert response .headers ["www-authenticate " ] == "Negotiate "
127
131
assert caplog .messages == ["Delegated credentials not found: '/tmp/does-not-exist'" ]
0 commit comments