2
2
3
3
/*
4
4
* This is a custom auth handler that will receive headers for the username and fullname
5
- * If the headers are missing, login will fail.
6
- * If the headers are present, login will succeed , and user will be added.
5
+ * If the headers are missing, the user will be presented with the login
6
+ * If the headers are present, login will be done automatically , and the user will be added to the system
7
7
*/
8
8
namespace Filegator \Services \Auth \Adapters ;
9
9
10
10
use Filegator \Services \Auth \Adapters \JsonFile ;
11
11
use Filegator \Services \Auth \User ;
12
+ use Filegator \Services \Logger \LoggerInterface ;
13
+ use Filegator \Services \Session \SessionStorageInterface as Session ;
12
14
13
15
class Header extends JsonFile
14
16
{
15
17
protected $ username_header_key ;
16
18
protected $ fullname_header_key ;
17
19
protected $ non_header_users ;
18
20
protected $ user_defaults ;
19
-
21
+ protected $ cookie_key ;
22
+
23
+ public function __construct (Session $ session , LoggerInterface $ logger )
24
+ {
25
+ parent ::__construct ($ session );
26
+ $ this ->logger = $ logger ;
27
+ }
28
+
20
29
public function init (array $ config = [])
21
30
{
22
31
parent ::init ($ config );
23
- $ this ->username_header_key = strtolower ($ config ["username_header_key " ]);
24
- $ this ->fullname_header_key = strtolower ($ config ["fullname_header_key " ]);
32
+ $ this ->username_header_key = $ config ["username_header_key " ];
33
+ $ this ->fullname_header_key = $ config ["fullname_header_key " ];
34
+ $ this ->cookie_key = $ config ["cookie_key " ] ?? "Cookie " ;
25
35
$ this ->ignore_users = $ config ["ignore_users " ] ?? [];
26
36
$ this ->user_defaults = $ config ["user_defaults " ] ?? [];
27
37
}
@@ -31,29 +41,55 @@ private function useNormalAuth($username): bool
31
41
return in_array ($ username , $ this ->ignore_users );
32
42
}
33
43
34
- private function headerUser (): array
44
+ private function cookieHeaders ($ headers ) {
45
+ $ all_headers = $ headers ;
46
+ if (!array_key_exists (strtolower ($ this ->cookie_key ), $ all_headers )) {
47
+ return [];
48
+ }
49
+
50
+ $ headers_from_cookie = explode ('; ' , $ all_headers ["cookie " ]);
51
+ $ headers = [];
52
+
53
+ foreach ($ headers_from_cookie as $ cookie ) {
54
+ list ($ key , $ value ) = explode ('= ' , $ cookie , 2 );
55
+ $ headers [$ key ] = $ value ;
56
+ }
57
+
58
+ return $ headers ;
59
+ }
60
+
61
+ private function trimQuotes ($ value ): string
62
+ {
63
+ if (! isset ($ value )) return $ value ;
64
+ return trim ($ value , '\'" ' );
65
+ }
66
+
67
+ private function headerUser (): ?array
35
68
{
36
69
$ headers = array_change_key_case (getallheaders (), CASE_LOWER );
37
- $ header_username_exists = array_key_exists ($ this ->username_header_key , $ headers );
38
- $ header_fullname_exists = array_key_exists ($ this ->fullname_header_key , $ headers );
70
+ $ cookie_headers = array_change_key_case ($ this ->cookieHeaders ($ headers ), CASE_LOWER );
71
+ $ username_header_key = strtolower ($ this ->username_header_key );
72
+ $ fullname_header_key = strtolower ($ this ->fullname_header_key );
73
+ $ header_username_exists = (array_key_exists ($ username_header_key , $ headers ) or array_key_exists ($ username_header_key , $ cookie_headers ));
74
+ $ header_fullname_exists = (array_key_exists ($ fullname_header_key , $ headers ) or array_key_exists ($ fullname_header_key , $ cookie_headers ));
39
75
40
76
if (!$ header_username_exists ) {
41
- error_log (print_r ($ this ->username_header_key ." header is not set " , true ));
77
+ $ this ->logger ->log ($ this ->username_header_key ." username header is not set " );
78
+ return null ;
42
79
}
43
80
if (!$ header_fullname_exists ) {
44
- error_log ( print_r ( $ this ->fullname_header_key ." header is not set " , true ) );
81
+ $ this -> logger -> log ( $ this ->fullname_header_key ." full name header is not set, falling back to username header " );
45
82
}
46
- if (!$ header_username_exists || !$ header_fullname_exists ) return null ;
47
83
48
- $ username_header = $ headers [$ this -> username_header_key ];
49
- $ fullname_header = $ headers [$ this -> fullname_header_key ];
84
+ $ username_header = $ headers [$ username_header_key ] ?? $ cookie_headers [ $ username_header_key ];
85
+ $ fullname_header = $ headers [$ fullname_header_key ] ?? $ cookie_headers [ $ fullname_header_key ] ?? $ username_header ;
50
86
51
87
if (!isset ($ username_header ) || empty ($ username_header )) return null ;
52
88
if (!isset ($ fullname_header ) || empty ($ fullname_header )) return null ;
53
89
54
90
return [
55
- "username " => $ username_header ,
56
- "name " => $ fullname_header ,
91
+ "username " => $ this -> trimQuotes ( $ username_header) ,
92
+ "name " => $ this -> trimQuotes ( $ fullname_header) ,
57
93
"role " => $ this ->user_defaults ["role " ] ?? "user " ,
58
94
"homedir " => $ this ->user_defaults ["homedir " ] ?? "/share " ,
59
95
"permissions " => $ this ->user_defaults ["permissions " ] ?? "read " ,
@@ -65,11 +101,22 @@ private function userHash($user): string
65
101
return $ user ->getHomedir ().$ user ->getRole ().$ user ->getUsername ();
66
102
}
67
103
104
+ private function setSessionHash ($ user ) {
105
+ $ this ->session ->set (self ::SESSION_HASH , $ this ->userHash ($ user ));
106
+ }
107
+
68
108
public function authenticate ($ username , $ password ): bool
69
109
{
70
110
if ($ this ->useNormalAuth ($ username )) {
71
- error_log (print_r ("** " .$ username ." user is configured to use normal authentication, skipping header auth " , true ));
72
- return parent ::authenticate ($ username , $ password );
111
+ $ this ->logger ->log ("** [ " .$ username ."] user is configured to use normal authentication, skipping header auth " );
112
+ $ authenticated = parent ::authenticate ($ username , $ password );
113
+ if ($ authenticated ) {
114
+ $ authenticated_user = parent ::user ();
115
+ if (isset ($ authenticated_user )) {
116
+ $ this ->setSessionHash ($ authenticated_user );
117
+ }
118
+ }
119
+ return $ authenticated ;
73
120
}
74
121
75
122
$ header_user = $ this ->headerUser ();
@@ -82,23 +129,35 @@ public function authenticate($username, $password): bool
82
129
}
83
130
84
131
$ this ->store ($ existing_user );
85
- $ this ->session -> set ( self :: SESSION_HASH , $ this -> userHash ( $ existing_user) );
132
+ $ this ->setSessionHash ( $ existing_user );
86
133
return true ;
87
134
}
88
135
136
+ protected function sessionUser () {
137
+ return $ this ->session ->get (self ::SESSION_KEY , null );
138
+ }
139
+
89
140
public function user (): ?User
90
141
{
91
142
if (! $ this ->session ) return null ;
92
-
93
- $ user = $ this ->session ->get (self ::SESSION_KEY , null );
94
- if (! $ user ) return null ;
95
143
96
- if ($ this ->useNormalAuth ($ user ->getUsername ())) return parent ::user ();
144
+ $ session_user = $ this ->sessionUser ();
145
+ if (isset ($ session_user )) {
146
+ $ hash = $ this ->session ->get (self ::SESSION_HASH , null );
147
+ return ($ hash == $ this ->userHash ($ session_user )) ? $ session_user : null ;
148
+ }
97
149
98
- $ existing_user = $ this ->find ($ user ->getUsername ());
99
- if (! $ existing_user ) return null ;
150
+ $ header_user = $ this ->headerUser ();
151
+ if (isset ($ header_user )) {
152
+ $ header_username = $ header_user ["username " ];
153
+ $ authenticated = $ this ->authenticate ($ header_username , "" );
154
+ if ($ authenticated ) {
155
+ $ authenticated_user = $ this ->sessionUser ();
156
+ $ this ->logger ->log ("Authenticated user [ " .$ authenticated_user ->getUsername ()."] with " .$ this ->username_header_key ." header " );
157
+ return $ authenticated_user ;
158
+ }
159
+ }
100
160
101
- $ hash = $ this ->session ->get (self ::SESSION_HASH , null );
102
- return ($ hash == $ this ->userHash ($ existing_user )) ? $ user : null ;
161
+ return null ;
103
162
}
104
163
}
0 commit comments