Passed
Push — master ( 7ec15a...e3834a )
by Stefan
03:36
created

commonSbProfileChecks()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 14
nc 16
nop 1
1
<?php
2
3
/*
4
 * ******************************************************************************
5
 * Copyright 2011-2017 DANTE Ltd. and GÉANT on behalf of the GN3, GN3+, GN4-1 
6
 * and GN4-2 consortia
7
 *
8
 * License: see the web/copyright.php file in the file structure
9
 * ******************************************************************************
10
 */
11
?>
12
<?php
13
14
require_once(dirname(dirname(dirname(__FILE__))) . "/config/_config.php");
15
16
function commonSbProfileChecks($id) {
17
    $validator = new \web\lib\common\InputValidation();
18
    $adminApi = new \web\lib\admin\API();
19
    try {
20
        $profile = $validator->Profile($id);
21
        } catch(Exception $e) {
22
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "Profile identifier does not exist!");
23
        }
24
        if (!$profile instanceof core\ProfileSilverbullet) {
25
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "Profile identifier is not SB!");
26
        }
27
        $idp = $profile->identifier;
28
        if (strtoupper($idp->federation) != strtoupper($fed->tld)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $fed seems to be never defined.
Loading history...
Bug introduced by
The property federation does not exist on integer.
Loading history...
29
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "Profile is not in the federation for this APIKEY!");
30
        }
31
        if (count($profile->getAttributes("hiddenprofile:tou_accepted")) < 1) {
32
            $adminApi->returnError(web\lib\admin\API::ERROR_NO_TOU, "The terms of use have not yet been accepted for this profile!");
33
        }
34
        return [$idp, $profile];
35
}
36
37
// no SAML auth on this page. The API key authenticates the entity
38
39
$mode = "API";
40
41
$adminApi = new \web\lib\admin\API();
42
$validator = new \web\lib\common\InputValidation();
43
$optionParser = new \web\lib\admin\OptionParser();
44
45
if (!isset(CONFIG['registration_API_keys']) || count(CONFIG['registration_API_keys']) == 0) {
46
    $adminApi->returnError(web\lib\admin\API::ERROR_API_DISABLED, "API is disabled in this instance of CAT");
47
}
48
49
$inputRaw = file_get_contents('php://input');
50
$inputDecoded = json_decode($inputRaw, TRUE);
51
if (!is_array($inputDecoded)) {
52
    $adminApi->returnError(web\lib\admin\API::ERROR_MALFORMED_REQUEST, "Unable to decode JSON POST data.");
53
}
54
55
if (!isset($inputDecoded['APIKEY'])) {
56
    $adminApi->returnError(web\lib\admin\API::ERROR_NO_APIKEY, "JSON request structure did not contain an APIKEY");
57
}
58
59
$checkval = "FAIL";
60
foreach (CONFIG['registration_API_keys'] as $key => $fed_name) {
61
    if ($inputDecoded['APIKEY'] == $key) {
62
        $mode = "API";
63
        $federation = $fed_name;
64
        $checkval = "OK-NEW";
65
    }
66
}
67
68
if ($checkval == "FAIL") {
69
    $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_APIKEY, "APIKEY is invalid");
70
}
71
72
// let's instantiate the fed, we will need it later
73
$fed = new \core\Federation($federation);
74
// it's a valid admin; what does he want to do?
75
if (!array_key_exists($inputDecoded['ACTION'], web\lib\admin\API::ACTIONS)) {
76
    $adminApi->returnError(web\lib\admin\API::ERROR_NO_ACTION, "JSON request structure did not contain a valid ACTION");
77
}
78
// it's a valid ACTION, so let's sanitise the input parameters
79
$scrubbedParameters = $adminApi->scrub($inputDecoded, $fed);
80
$paramNames = [];
81
foreach ($scrubbedParameters as $oneParam) {
82
    $paramNames[] = $oneParam['NAME'];
83
}
84
// are all the required parameters (still) in the request?
85
foreach (web\lib\admin\API::ACTIONS[$inputDecoded['ACTION']]['REQ'] as $oneRequiredAttribute) {
86
    if (!in_array($oneRequiredAttribute, $paramNames)) {
87
        $adminApi->returnError(web\lib\admin\API::ERROR_MISSING_PARAMETER, "At least one required parameter for this ACTION is missing: $oneRequiredAttribute");
88
    }
89
}
90
91
switch ($inputDecoded['ACTION']) {
92
    case web\lib\admin\API::ACTION_NEWINST:
93
        // create the inst, no admin, no attributes
94
        $idp = new \core\IdP($fed->newIdP("PENDING", "API"));
95
        // now add all submitted attributes
96
        $inputs = $adminApi->uglify($scrubbedParameters);
97
        $optionParser->processSubmittedFields($idp, $inputs["POST"], $inputs["FILES"]);
98
        $adminApi->returnSuccess([web\lib\admin\API::AUXATTRIB_CAT_INST_ID => $idp->identifier]);
99
        break;
100
    case web\lib\admin\API::ACTION_DELINST:
101
        try {
102
        $idp = $validator->IdP($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_CAT_INST_ID));
103
        } catch(Exception $e) {
104
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "IdP identifier does not exist!");
105
        }
106
        $idp->destroy();
107
        $adminApi->returnSuccess([]);
108
        break;
109
    case web\lib\admin\API::ACTION_ADMIN_LIST:
110
        try {
111
        $idp = $validator->IdP($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_CAT_INST_ID));
112
        } catch(Exception $e) {
113
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "IdP identifier does not exist!");
114
        }
115
        $adminApi->returnSuccess($idp->listOwners());
116
        break;
117
    case web\lib\admin\API::ACTION_ADMIN_ADD:
118
        // IdP in question
119
        try {
120
        $idp = $validator->IdP($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_CAT_INST_ID));
121
        } catch(Exception $e) {
122
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "IdP identifier does not exist!");
123
        }
124
        // here is the token
125
        $mgmt = new core\UserManagement();
126
        // we know we have an admin ID but scrutinizer wants this checked more explicitly
127
        $admin = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_ADMINID);
128
        if ($admin === FALSE) {
129
            throw new Exception("A required parameter is missing, and this wasn't caught earlier?!");
130
        }
131
        $newtoken = $mgmt->createToken(true, $admin, $idp);
132
        $URL = "https://" . $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']) . "/action_enrollment.php?token=$newtoken";
133
        $success = ["TOKEN URL" => $URL];
134
        // done with the essentials - display in response. But if we also have an email address, send it there
135
        $email = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_ADMINEMAIL);
136
        if ($email !== FALSE) {
137
            $sent = \core\common\OutsideComm::adminInvitationMail($email, "EXISTING-FED", $newtoken, $idp->name, $fed);
138
            $success["EMAIL SENT"] = $sent["SENT"];
139
            if ($sent["SENT"] === TRUE) {
140
                $success["EMAIL TRANSPORT SECURE"] = $sent["TRANSPORT"];
141
            }
142
        }
143
        $adminApi->returnSuccess($success);
144
        break;
145
    case web\lib\admin\API::ACTION_ADMIN_DEL:
146
        // IdP in question
147
        try {
148
        $idp = $validator->IdP($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_CAT_INST_ID));
149
        } catch(Exception $e) {
150
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "IdP identifier does not exist!");
151
        }
152
        $currentAdmins = $idp->listOwners();
153
        $toBeDeleted = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_ADMINID);
154
        if ($toBeDeleted === FALSE) {
155
            throw new Exception("A required parameter is missing, and this wasn't caught earlier?!");
156
        }
157
        $found = FALSE;
158
        foreach($currentAdmins as $oneAdmin) {
159
            if ($oneAdmin['MAIL'] == $toBeDeleted) {
160
                $found = TRUE;
161
                $mgmt = new core\UserManagement();
162
                $mgmt->removeAdminFromIdP($idp, $oneAdmin['ID']);
163
            }
164
        }
165
        if ($found) {
166
            $adminApi->returnSuccess([]);
167
        }
168
        $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "The admin with ID $toBeDeleted is not associated to IdP ".$idp->identifier);
169
        break;
170
    case web\lib\admin\API::ACTION_STATISTICS_FED:
171
        $adminApi->returnSuccess($fed->downloadStats("array"));
172
        break;
173
    case \web\lib\admin\API::ACTION_NEWPROF_RADIUS:
174
        // fall-through intended: both get mostly identical treatment
175
    case web\lib\admin\API::ACTION_NEWPROF_SB:
176
        try {
177
        $idp = $validator->IdP($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_CAT_INST_ID));
178
        } catch(Exception $e) {
179
            $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_PARAMETER, "IdP identifier does not exist!");
180
        }
181
        if ($inputDecoded['ACTION'] == web\lib\admin\API::ACTION_NEWPROF_RADIUS) {
182
            $type = "RADIUS";
183
        } else {
184
            $type = "SILVERBULLET";
185
        }
186
        $profile = $idp->newProfile($type);
187
        if ($profile === NULL) {
188
            $adminApi->returnError(\web\lib\admin\API::ERROR_INTERNAL_ERROR, "Unable to create a new Profile, for no apparent reason. Please contact support.");
189
        }
190
        $inputs = $adminApi->uglify($scrubbedParameters);
191
        $optionParser->processSubmittedFields($profile, $inputs["POST"], $inputs["FILES"]);
192
        if ($inputDecoded['ACTION'] == web\lib\admin\API::ACTION_NEWPROF_SB) {
193
            // auto-accept ToU?
194
            if ($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_SB_TOU) !== FALSE) {
195
                $profile->addAttribute("hiddenprofile:tou_accepted", NULL, TRUE);
196
            }
197
            // we're done at this point
198
            $adminApi->returnSuccess([\web\lib\admin\API::AUXATTRIB_CAT_PROFILE_ID => $profile->identifier]);
199
            continue;
200
        }
201
        if (!$profile instanceof core\ProfileRADIUS) {
202
            throw new Exception("Can't be. This is only here to convince Scrutinizer that we're really talking RADIUS.");
203
        }
204
        /* const AUXATTRIB_PROFILE_REALM = 'ATTRIB-PROFILE-REALM';
205
           const AUXATTRIB_PROFILE_OUTERVALUE = 'ATTRIB-PROFILE-OUTERVALUE';*/
206
        $realm = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_PROFILE_REALM);
207
        $outer = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_PROFILE_OUTERVALUE);
208
        if ($realm !== FALSE) {
209
            if ($outer === FALSE) {
210
                $outer = "";
211
                $profile->setAnonymousIDSupport(FALSE);
212
            } else {
213
                $outer = $outer."@";
214
                $profile->setAnonymousIDSupport(TRUE);
215
            }
216
            $profile->setRealm($outer.$realm);
217
        }
218
        /* const AUXATTRIB_PROFILE_TESTUSER = 'ATTRIB-PROFILE-TESTUSER';*/
219
        $testuser = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_PROFILE_TESTUSER);
220
        if ($testuser !== FALSE) {
221
            $profile->setRealmCheckUser(TRUE, $testuser);
222
        }        
223
        /* const AUXATTRIB_PROFILE_INPUT_HINT = 'ATTRIB-PROFILE-HINTREALM';
224
           const AUXATTRIB_PROFILE_INPUT_VERIFY = 'ATTRIB-PROFILE-VERIFYREALM'; */
225
        $hint = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_PROFILE_INPUT_HINT);
226
        $enforce = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_PROFILE_INPUT_VERIFY);
227
        if ($enforce !== FALSE) {
228
            $profile->setInputVerificationPreference($enforce, $hint);
229
        }
230
        /* const AUXATTRIB_PROFILE_EAPTYPE */
231
        $iterator = 1;
232
        foreach ($scrubbedParameters as $oneParam) {
233
            if ($oneParam['NAME'] == web\lib\admin\API::AUXATTRIB_PROFILE_EAPTYPE && is_int($oneParam["VALUE"])) {
234
                $type = new \core\common\EAP($oneParam["VALUE"]);
235
                $profile->addSupportedEapMethod($type, $iterator);
236
                $iterator = $iterator+1;
237
            }
238
        }
239
        $adminApi->returnSuccess([\web\lib\admin\API::AUXATTRIB_CAT_PROFILE_ID => $profile->identifier]);
240
        break;
241
    case web\lib\admin\API::ACTION_ENDUSER_NEW:
242
        list($idp, $profile) = commonSbProfileChecks($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_CAT_PROFILE_ID));
243
        $user = $validator->string($adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_SB_USERNAME));
244
        $expiryRaw = $adminApi->firstParameterInstance($scrubbedParameters, web\lib\admin\API::AUXATTRIB_SB_EXPIRY);
245
        $expiry = new DateTime($expiryRaw);
0 ignored issues
show
Bug introduced by
It seems like $expiryRaw can also be of type false; however, parameter $time of DateTime::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

245
        $expiry = new DateTime(/** @scrutinizer ignore-type */ $expiryRaw);
Loading history...
246
        $retval = $profile->addUser($user, $expiry);
247
        if ($retval == 0) {// that didn't work, it seems
248
            $adminApi->returnError(web\lib\admin\API::ERROR_INTERNAL_ERROR, "The operation failed. Maybe a duplicate username, or malformed expiry date?");
249
        }
250
        $adminApi->returnSuccess([web\lib\admin\API::AUXATTRIB_SB_USERNAME => $user]);
251
        
252
    default:
253
        $adminApi->returnError(web\lib\admin\API::ERROR_INVALID_ACTION, "Not implemented yet.");
254
}
255