99/**
1010 * Class sspmod_perun_Auth_Process_ProxyFilter
1111 *
12- * This filter allows to disable nested filter for particular SP
13- * or for users with one of (black)listed attribute values.
14- * When any of the values matches, the nested filter is NOT run.
12+ * This filter allows to disable/enable nested filter for particular SP
13+ * or for users with one of (black/white)listed attribute values.
14+ * Based on the mode of operation, the nested filter
15+ * IS (whitelist) or IS NOT (blacklist) run when any of the attribute values matches.
1516 * SPs are defined by theirs entityID in property 'filterSPs'.
1617 * User attributes are defined as a map 'attrName'=>['value1','value2']
1718 * in property 'filterAttributes'.
3031 * 'class' => 'perun:NestedFilter',
3132 * // ...
3233 * ],
33- * ]
34+ * ],
35+ * 20 => [
36+ * 'class' => 'perun:ProxyFilter',
37+ * 'mode' => 'whitelist',
38+ * 'filterSPs' => ['enableSpEntityId01', 'enableSpEntityId02'],
39+ * 'config' => [
40+ * 'class' => 'perun:NestedFilter',
41+ * // ...
42+ * ],
43+ * ],
3444 *
3545 * @author Ondrej Velisek <[email protected] > 3646 */
3747class ProxyFilter extends \SimpleSAML \Auth \ProcessingFilter
3848{
49+ public const MODE_BLACKLIST = 'blacklist ' ;
50+ public const MODE_WHITELIST = 'whitelist ' ;
51+ public const MODES = [
52+ self ::MODE_BLACKLIST ,
53+ self ::MODE_WHITELIST ,
54+ ];
3955
4056 private $ config ;
4157 private $ nestedClass ;
4258 private $ filterSPs ;
4359 private $ filterAttributes ;
60+ private $ mode ;
4461 private $ reserved ;
4562
4663 public function __construct ($ config , $ reserved )
@@ -53,6 +70,7 @@ public function __construct($config, $reserved)
5370 unset($ this ->config ['class ' ]);
5471 $ this ->filterSPs = $ conf ->getArray ('filterSPs ' , []);
5572 $ this ->filterAttributes = $ conf ->getArray ('filterAttributes ' , []);
73+ $ this ->mode = $ conf ->getValueValidate ('mode ' , self ::MODES , self ::MODE_BLACKLIST );
5674
5775 $ this ->reserved = (array )$ reserved ;
5876 }
@@ -61,42 +79,63 @@ public function process(&$request)
6179 {
6280 assert (is_array ($ request ));
6381
64- foreach ($ this ->filterAttributes as $ attr => $ values ) {
65- if (!isset ($ request ['Attributes ' ][$ attr ]) || !is_array ($ request ['Attributes ' ][$ attr ])) {
66- continue ;
67- }
68- foreach ($ values as $ value ) {
69- if (in_array ($ value , $ request ['Attributes ' ][$ attr ])) {
70- Logger::info (
71- sprintf (
72- 'perun.ProxyFilter: Filtering out filter %s because %s contains %s ' ,
73- $ this ->nestedClass ,
74- $ attr ,
75- $ value
76- )
77- );
82+ $ default = $ this ->mode === self ::MODE_BLACKLIST ;
83+ $ shouldRun = $ this ->shouldRunForSP ($ request ['Destination ' ]['entityid ' ], $ default );
84+ if ($ shouldRun === $ default ) {
85+ $ shouldRun = $ this ->shouldRunForAttribute ($ request ['Attributes ' ], $ default );
86+ }
7887
79- return ;
80- }
81- }
88+ if ($ shouldRun ) {
89+ $ this ->runAuthProcFilter ($ request );
8290 }
91+ }
8392
93+ private function shouldRunForSP ($ currentSp , $ default )
94+ {
8495 foreach ($ this ->filterSPs as $ sp ) {
85- $ currentSp = $ request ['Destination ' ]['entityid ' ];
8696 if ($ sp === $ currentSp ) {
97+ $ shouldRun = !$ default ;
8798 Logger::info (
8899 sprintf (
89- 'perun.ProxyFilter: Filtering out filter %s for SP %s ' ,
100+ 'perun.ProxyFilter: %s filter %s for SP %s ' ,
101+ $ shouldRun ? 'Running ' : 'Filtering out ' ,
90102 $ this ->nestedClass ,
91103 $ currentSp
92104 )
93105 );
106+ return $ shouldRun ;
107+ }
108+ }
109+ return $ default ;
110+ }
94111
95- return ;
112+ private function shouldRunForAttribute ($ attributes , $ default )
113+ {
114+ foreach ($ this ->filterAttributes as $ attr => $ values ) {
115+ if (isset ($ attributes [$ attr ]) && is_array ($ attributes [$ attr ])) {
116+ foreach ($ values as $ value ) {
117+ if (in_array ($ value , $ attributes [$ attr ])) {
118+ $ shouldRun = !$ default ;
119+ Logger::info (
120+ sprintf (
121+ 'perun.ProxyFilter: %s filter %s because %s contains %s ' ,
122+ $ shouldRun ? 'Running ' : 'Filtering out ' ,
123+ $ this ->nestedClass ,
124+ $ attr ,
125+ $ value
126+ )
127+ );
128+ return $ shouldRun ;
129+ }
130+ }
96131 }
97132 }
133+ return $ default ;
134+ }
98135
99- list ($ module , $ simpleClass ) = explode (": " , $ this ->nestedClass );
136+ private function runAuthProcFilter (&$ request )
137+ {
138+ list ($ module , $ simpleClass ) = explode (': ' , $ this ->nestedClass );
100139 $ className = '\SimpleSAML\Module \\' . $ module . '\Auth\Process \\' . $ simpleClass ;
101140 $ authFilter = new $ className ($ this ->config , $ this ->reserved );
102141 $ authFilter ->process ($ request );
0 commit comments