Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Class for loading/storing issuers from the DB.
19
 *
20
 * @package    core
21
 * @copyright  2017 Damyon Wiese
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
namespace core\oauth2;
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
use core\persistent;
29
use lang_string;
30
 
31
/**
32
 * Class for loading/storing issuer from the DB
33
 *
34
 * @copyright  2017 Damyon Wiese
35
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 */
37
class issuer extends persistent {
38
 
39
    /** @var int Issuer is displayed on both login page and in the services lists */
40
    const EVERYWHERE = 1;
41
    /** @var int Issuer is displayed on the login page only */
42
    const LOGINONLY = 2;
1441 ariadna 43
    /** @var int Issuer is used for sending email using SMTP with XOAUTH2 */
44
    const SMTPWITHXOAUTH2 = 3;
1 efrain 45
    /** @var int Issuer is displayed only in the services lists and can not be used for login */
46
    const SERVICEONLY = 0;
47
 
48
    const TABLE = 'oauth2_issuer';
49
 
50
    /**
51
     * Return the definition of the properties of this model.
52
     *
53
     * @return array
54
     */
55
    protected static function define_properties() {
56
        return array(
57
            'name' => array(
58
                'type' => PARAM_TEXT
59
            ),
60
            'image' => array(
61
                'type' => PARAM_URL,
62
                'null' => NULL_ALLOWED,
63
                'default' => null
64
            ),
65
            'clientid' => array(
66
                'type' => PARAM_RAW_TRIMMED,
67
                'default' => ''
68
            ),
69
            'clientsecret' => array(
70
                'type' => PARAM_RAW_TRIMMED,
71
                'default' => ''
72
            ),
73
            'baseurl' => array(
74
                'type' => PARAM_URL,
75
                'default' => ''
76
            ),
77
            'enabled' => array(
78
                'type' => PARAM_BOOL,
79
                'default' => true
80
            ),
81
            'showonloginpage' => array(
82
                'type' => PARAM_INT,
83
                'default' => self::SERVICEONLY,
84
            ),
85
            'basicauth' => array(
86
                'type' => PARAM_BOOL,
87
                'default' => false
88
            ),
89
            'scopessupported' => array(
90
                'type' => PARAM_RAW,
91
                'null' => NULL_ALLOWED,
92
                'default' => null
93
            ),
94
            'loginscopes' => array(
95
                'type' => PARAM_RAW,
96
                'default' => 'openid profile email'
97
            ),
98
            'loginscopesoffline' => array(
99
                'type' => PARAM_RAW,
100
                'default' => 'openid profile email'
101
            ),
102
            'loginparams' => array(
103
                'type' => PARAM_RAW,
104
                'default' => ''
105
            ),
106
            'loginparamsoffline' => array(
107
                'type' => PARAM_RAW,
108
                'default' => ''
109
            ),
110
            'alloweddomains' => array(
111
                'type' => PARAM_RAW,
112
                'default' => ''
113
            ),
114
            'sortorder' => array(
115
                'type' => PARAM_INT,
116
                'default' => 0,
117
            ),
118
            'requireconfirmation' => array(
119
                'type' => PARAM_BOOL,
120
                'default' => true
121
            ),
122
            'servicetype' => array(
123
                'type' => PARAM_ALPHANUM,
124
                'null' => NULL_ALLOWED,
125
                'default' => null,
126
            ),
127
            'loginpagename' => array(
128
                'type' => PARAM_TEXT,
129
                'null' => NULL_ALLOWED,
130
                'default' => null,
131
            ),
1441 ariadna 132
            'systememail' => [
133
                'type' => PARAM_EMAIL,
134
                'null' => NULL_ALLOWED,
135
                'default' => null,
136
            ],
1 efrain 137
        );
138
    }
139
 
140
    /**
141
     * Hook to execute before validate.
142
     *
143
     * @return void
144
     */
145
    protected function before_validate() {
146
        if (($this->get('id') && $this->get('sortorder') === null) || !$this->get('id')) {
147
            $this->set('sortorder', $this->count_records());
148
        }
149
    }
150
 
151
    /**
152
     * Helper the get a named service endpoint.
153
     * @param string $type
154
     * @return string|false
155
     */
156
    public function get_endpoint_url($type) {
157
        $endpoint = endpoint::get_record([
158
            'issuerid' => $this->get('id'),
159
            'name' => $type . '_endpoint'
160
        ]);
161
 
162
        if ($endpoint) {
163
            return $endpoint->get('url');
164
        }
165
        return false;
166
    }
167
 
168
    /**
169
     * Perform matching against the list of allowed login domains for this issuer.
170
     *
171
     * @param string $email The email to check.
172
     * @return boolean
173
     */
174
    public function is_valid_login_domain($email) {
175
        if (empty($this->get('alloweddomains'))) {
176
            return true;
177
        }
178
 
179
        $validdomains = explode(',', $this->get('alloweddomains'));
180
 
181
        $parts = explode('@', $email, 2);
182
        $emaildomain = '';
183
        if (count($parts) > 1) {
184
            $emaildomain = $parts[1];
185
        }
186
 
187
        return \core\ip_utils::is_domain_in_allowed_list($emaildomain, $validdomains);
188
    }
189
 
190
    /**
191
     * Does this OAuth service support user authentication?
192
     * @return boolean
193
     */
194
    public function is_authentication_supported() {
195
        debugging('Method is_authentication_supported() is deprecated, please use is_available_for_login()',
196
            DEBUG_DEVELOPER);
197
        return (!empty($this->get_endpoint_url('userinfo')));
198
    }
199
 
200
    /**
201
     * Is this issue fully configured and enabled and can be used for login/signup
202
     *
203
     * @return bool
204
     * @throws \coding_exception
205
     */
206
    public function is_available_for_login(): bool {
207
        return $this->get('id') &&
208
            $this->is_configured() &&
209
            $this->get('showonloginpage') != self::SERVICEONLY &&
1441 ariadna 210
            $this->get('showonloginpage') != self::SMTPWITHXOAUTH2 &&
1 efrain 211
            $this->get('enabled') &&
212
            !empty($this->get_endpoint_url('userinfo'));
213
    }
214
 
215
    /**
216
     * Return true if this issuer looks like it has been configured.
217
     *
218
     * @return boolean
219
     */
220
    public function is_configured() {
221
        return (!empty($this->get('clientid')) && !empty($this->get('clientsecret')));
222
    }
223
 
224
    /**
225
     * Do we have a refresh token for a system account?
226
     * @return boolean
227
     */
228
    public function is_system_account_connected() {
229
        if (!$this->is_configured()) {
230
            return false;
231
        }
232
        $sys = system_account::get_record(['issuerid' => $this->get('id')]);
233
        if (empty($sys) || empty($sys->get('refreshtoken'))) {
234
            return false;
235
        }
236
 
237
        $scopes = api::get_system_scopes_for_issuer($this);
238
 
239
        $grantedscopes = $sys->get('grantedscopes');
240
 
241
        $scopes = explode(' ', $scopes);
242
 
243
        foreach ($scopes as $scope) {
244
            if (!empty($scope)) {
245
                if (strpos(' ' . $grantedscopes . ' ', ' ' . $scope . ' ') === false) {
246
                    // We have not been granted all the scopes that are required.
247
                    return false;
248
                }
249
            }
250
        }
251
 
252
        return true;
253
    }
254
 
255
    /**
256
     * Custom validator for end point URLs.
257
     * Because we send Bearer tokens we must ensure SSL.
258
     *
259
     * @param string $value The value to check.
260
     * @return lang_string|boolean
261
     */
262
    protected function validate_baseurl($value) {
263
        global $CFG;
264
        include_once($CFG->dirroot . '/lib/validateurlsyntax.php');
265
        if (!empty($value) && !validateUrlSyntax($value, 'S+')) {
266
            return new lang_string('sslonlyaccess', 'error');
267
        }
268
        return true;
269
    }
270
 
271
    /**
272
     * Display name for the issuers used on the login page
273
     *
274
     * @return string
275
     */
276
    public function get_display_name(): string {
277
        return $this->get('loginpagename') ? $this->get('loginpagename') : $this->get('name');
278
    }
1441 ariadna 279
 
280
    /**
281
     * Get the system email address for this issuer.
282
     *
283
     * @return string|null The system email address or null if not set.
284
     */
285
    public function get_system_email(): ?string {
286
        return $this->get('systememail') ? $this->get('systememail') : null;
287
    }
1 efrain 288
}