SamlEntity::toServiceProvider()   B
last analyzed

Complexity

Conditions 6
Paths 17

Size

Total Lines 45
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 25
nc 17
nop 0
dl 0
loc 45
rs 8.8977
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupGateway\GatewayBundle\Entity;
20
21
use Doctrine\ORM\Mapping as ORM;
22
use GuzzleHttp;
23
use Surfnet\SamlBundle\Entity\IdentityProvider;
24
use Surfnet\StepupGateway\GatewayBundle\Exception\RuntimeException;
25
26
/**
27
 *
28
 * @SuppressWarnings(PHPMD.UnusedPrivateField)
29
 */
30
#[ORM\Entity(repositoryClass: \Surfnet\StepupGateway\GatewayBundle\Entity\DoctrineSamlEntityRepository::class)]
31
#[ORM\Table]
32
class SamlEntity
33
{
34
    /**
35
     * Constants denoting the type of SamlEntity. Also used in the middleware to make that distinction
36
     */
37
    public const TYPE_IDP = 'idp';
38
    public const TYPE_SP = 'sp';
39
40
    /**
41
     * @var string
42
     */
43
    #[ORM\Id]
44
    #[ORM\Column(length: 36)]
45
    private $id;
0 ignored issues
show
introduced by
The private property $id is not used, and could be removed.
Loading history...
46
47
    /**
48
     * @var string
49
     */
50
    #[ORM\Column]
51
    private $entityId;
52
53
    /**
54
     * @var string
55
     */
56
    #[ORM\Column]
57
    private $type;
58
59
    /**
60
     * @var string the configuration as json string
61
     */
62
    #[ORM\Column(type: 'text')]
63
    private $configuration;
64
65
    /**
66
     * @return IdentityProvider
67
     */
68
    public function toIdentityProvider()
69
    {
70
        if (!$this->type === self::TYPE_IDP) {
0 ignored issues
show
introduced by
The condition ! $this->type === self::TYPE_IDP is always false.
Loading history...
71
            throw new RuntimeException(sprintf(
72
                'Cannot cast a SAMLEntity to an IdentityProvider if it is not of the type "%s", current type: "%s"',
73
                self::TYPE_IDP,
74
                $this->type
75
            ));
76
        }
77
78
        $decodedConfiguration = $this->decodeConfiguration();
79
80
        // index based will be supported later on
81
        $configuration = [];
82
        $configuration['entityId']             = $this->entityId;
83
        $configuration['configuredLoas']       = $decodedConfiguration['loa'];
84
85
        return new IdentityProvider($configuration);
86
    }
87
88
    /**
89
     * @return ServiceProvider
90
     */
91
    public function toServiceProvider()
92
    {
93
        if (!$this->type === self::TYPE_SP) {
0 ignored issues
show
introduced by
The condition ! $this->type === self::TYPE_SP is always false.
Loading history...
94
            throw new RuntimeException(sprintf(
95
                'Cannot cast a SAMLEntity to a ServiceProvider if it is not of the type "%s", current type: "%s"',
96
                self::TYPE_SP,
97
                $this->type
98
            ));
99
        }
100
101
        $decodedConfiguration = $this->decodeConfiguration();
102
103
        // Note that we don't set 'assertionConsumerUrl',
104
        // getAssertionConsumerUrl() on this service provider entity will
105
        // yield null. The ACS URL in the AuthnRequest is used instead, and
106
        // this URL is validated by matching against the configured 'allowed
107
        // ACS locations'. If it doesn't match, the gateway will fall back to
108
        // the first configured ACS location.
109
        $configuration = [];
110
        $configuration['allowedAcsLocations'] = $decodedConfiguration['acs'];
111
        $configuration['certificateData']     = $decodedConfiguration['public_key'];
112
        $configuration['entityId']            = $this->entityId;
113
        $configuration['configuredLoas']      = $decodedConfiguration['loa'];
114
115
        $configuration['secondFactorOnly'] = false;
116
        // Allow the sp to evaluate the SSO on 2FA cookie if present? (defaults to false)
117
        $configuration['allowSsoOn2fa'] = false;
118
        // Is the SP allowed to set a SSO on 2FA cookie in Gateway? (defautls to false)
119
        $configuration['setSsoCookieOn2fa'] = false;
120
121
        if (isset($decodedConfiguration['second_factor_only'])) {
122
            $configuration['secondFactorOnly'] = $decodedConfiguration['second_factor_only'];
123
        }
124
        $configuration['secondFactorOnlyNameIdPatterns'] = [];
125
        if (isset($decodedConfiguration['second_factor_only_nameid_patterns'])) {
126
            $configuration['secondFactorOnlyNameIdPatterns'] =
127
                $decodedConfiguration['second_factor_only_nameid_patterns'];
128
        }
129
        if (isset($decodedConfiguration['allow_sso_on_2fa'])) {
130
            $configuration['allowSsoOn2fa'] = $decodedConfiguration['allow_sso_on_2fa'];
131
        }
132
        if (isset($decodedConfiguration['set_sso_cookie_on_2fa'])) {
133
            $configuration['setSsoCookieOn2fa'] = $decodedConfiguration['set_sso_cookie_on_2fa'];
134
        }
135
        return new ServiceProvider($configuration);
136
    }
137
138
    /**
139
     * Returns the decoded configuration
140
     *
141
     * @return array
142
     */
143
    private function decodeConfiguration()
144
    {
145
        return GuzzleHttp\json_decode($this->configuration, true);
146
    }
147
}
148