AuthorizeByDest   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
c 1
b 0
f 0
dl 0
loc 127
rs 10
wmc 20

3 Methods

Rating   Name   Duplication   Size   Complexity  
A unauthorized() 0 6 1
A process() 0 22 6
C __construct() 0 32 13
1
<?php
2
3
namespace SimpleSAML\Module\authorizebydest\Auth\Process;
4
5
use SimpleSAML\Auth;
6
use SimpleSAML\Error\CriticalConfigurationError;
7
use SimpleSAML\Logger;
8
use SimpleSAML\Module;
9
use SimpleSAML\Utils;
10
use Webmozart\Assert\Assert;
11
12
/**
13
 * Filter to authorize only certain users.
14
 * See docs directory.
15
 *
16
 * @package SimpleSAMLphp
17
 */
18
class AuthorizeByDest extends Auth\ProcessingFilter
19
{
20
    /**
21
     * Flag to deny/unauthorize the user a attribute filter IS found
22
     *
23
     * @var string
24
     */
25
    protected $attribute;
26
27
    /**
28
     * @var string
29
     */
30
    protected $attribute_value;
31
32
    /**
33
     * @var array
34
     */
35
    protected $destination_whitelist = [];
36
37
    /**
38
     * @var string
39
     */
40
    protected $distinguish_attribute;
41
42
    /**
43
     * @var array
44
     */
45
    protected $distinguish_users = [];
46
47
    /**
48
     * Initialize this filter.
49
     * Validate configuration parameters.
50
     *
51
     * @param array $config   Configuration information about this filter.
52
     * @param mixed $reserved For future use.
53
     *
54
     * @throws CriticalConfigurationError
55
     */
56
    public function __construct(array $config, $reserved)
57
    {
58
        parent::__construct($config, $reserved);
59
60
        if (isset($config['attribute']) && is_string($config['attribute'])) {
61
            $this->attribute = $config['attribute'];
62
        } else {
63
            $reason = 'There is no attribute config in authorizeByDest authproc filter';
64
            throw new CriticalConfigurationError($reason);
65
        }
66
        if (isset($config['attribute_value']) && is_string($config['attribute_value'])) {
67
            $this->attribute_value = $config['attribute_value'];
68
        } else {
69
            $reason = 'There is no attribute_value config in authorizeByDest authproc filter';
70
            throw new CriticalConfigurationError($reason);
71
        }
72
        if (isset($config['destination_whitelist']) && is_array($config['destination_whitelist'])) {
73
            $this->destination_whitelist = $config['destination_whitelist'];
74
        } else {
75
            $reason = 'There is no destination_whitelist config in authorizeByDest authproc filter';
76
            throw new CriticalConfigurationError($reason);
77
        }
78
79
        if (isset($config['distinguish_attribute']) && is_string($config['distinguish_attribute'])) {
80
            $this->distinguish_attribute = $config['distinguish_attribute'];
81
        }
82
        if (isset($config['distinguish_users']) && is_array($config['distinguish_users'])) {
83
            $this->distinguish_users = $config['distinguish_users'];
84
        }
85
        if (isset($this->distinguish_users) and !isset($this->distinguish_attribute)) {
86
            $reason = 'You have to define distinguish attribute in authorizeByDest authproc filter';
87
            throw new CriticalConfigurationError($reason);
88
        }
89
    }
90
91
92
    /**
93
     * Apply filter to validate dest and user.
94
     *
95
     * @param array &$request The current request
96
     */
97
    public function process(&$request)
98
    {
99
        Assert::keyExists($request, 'Attributes');
100
        Assert::keyExists($request, 'SPMetadata');
101
        Assert::keyExists($request['SPMetadata'], 'entityid');
102
103
        $attributes = $request['Attributes'];
104
        $destination = $request['SPMetadata']['entityid'];
105
106
107
        Logger::debug("AuthorizeByDest distinguish values: " . json_encode([
108
            $this->distinguish_attribute,
109
            $attributes[$this->distinguish_attribute],
110
            $this->distinguish_users,
111
        ]));
112
113
        if (!empty($attributes[$this->distinguish_attribute])
114
            && empty(array_intersect($attributes[$this->distinguish_attribute], $this->distinguish_users))
115
        ) {
116
            if (!empty($attributes[$this->attribute]) && in_array($this->attribute_value, $attributes[$this->attribute])) {
117
                if (!in_array($destination, $this->destination_whitelist)) {
118
                    $this->unauthorized($request);
119
                }
120
            }
121
        }
122
123
124
    }
125
126
127
    /**
128
     * When the process logic determines that the user is not
129
     * authorized for this service, then forward the user to
130
     * an 403 unauthorized page.
131
     *
132
     * Separated this code into its own method so that child
133
     * classes can override it and change the action. Forward
134
     * thinking in case a "chained" ACL is needed, more complex
135
     * permission logic.
136
     *
137
     * @param array $request
138
     */
139
    protected function unauthorized(&$request)
140
    {
141
        // Save state and redirect to 403 page
142
        $id = Auth\State::saveState($request, 'authorizebydest:AuthorizeByDest');
143
        $url = Module::getModuleURL('authorizebydest/authorize_403.php');
144
        Utils\HTTP::redirectTrustedURL($url, ['StateId' => $id]);
145
    }
146
}
147