Subversion Repositories oidplus

Rev

Rev 1406 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
635 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
1149 daniel-mar 5
 * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
635 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
1050 daniel-mar 20
use ViaThinkSoft\OIDplus\OIDplus;
21
use ViaThinkSoft\OIDplus\OIDplusGui;
22
use ViaThinkSoft\OIDplus\OIDplusException;
23
use ViaThinkSoft\OIDplus\OIDplusRA;
24
 
635 daniel-mar 25
# More information about the OAuth2 implementation:
26
# - https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
27
# - https://developers.facebook.com/tools/explorer/
28
 
29
require_once __DIR__ . '/../../../../includes/oidplus.inc.php';
30
 
1050 daniel-mar 31
set_exception_handler(array(OIDplusGui::class, 'html_exception_handler'));
635 daniel-mar 32
 
1200 daniel-mar 33
OIDplus::init(true);
34
 
1050 daniel-mar 35
if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_ViaThinkSoft\OIDplus\OIDplusPagePublicLoginFacebook', false)) {
635 daniel-mar 36
        throw new OIDplusException(_L('This plugin was disabled by the system administrator!'));
37
}
38
 
39
if (!OIDplus::baseConfig()->getValue('FACEBOOK_OAUTH2_ENABLED', false)) {
40
        throw new OIDplusException(_L('Facebook OAuth authentication is disabled on this system.'));
41
}
42
 
43
_CheckParamExists($_GET, 'code');
44
_CheckParamExists($_GET, 'state');
45
_CheckParamExists($_COOKIE, 'csrf_token_weak');
46
 
1372 daniel-mar 47
$ary = explode('|', $_GET['state'], 2);
48
if (count($ary) !== 2) {
49
        die(_L('Invalid State'));
50
}
1413 daniel-mar 51
$redirect_uri = $ary[0] ?? ''; // Attention: Comes from the client. The OAuth2 server MUST verify it! (Google and Facebook does this)
52
$check_csrf = $ary[1] ?? '';
1372 daniel-mar 53
 
54
if ($check_csrf != $_COOKIE['csrf_token_weak']) {
866 daniel-mar 55
        die(_L('Missing or wrong CSRF Token'));
635 daniel-mar 56
}
57
 
58
// Get access token
59
 
1149 daniel-mar 60
$cont = url_post_contents(
61
        "https://graph.facebook.com/v8.0/oauth/access_token?".
62
                "client_id=".urlencode(OIDplus::baseConfig()->getValue('FACEBOOK_OAUTH2_CLIENT_ID'))."&".
1372 daniel-mar 63
                "redirect_uri=".urlencode($redirect_uri)."&".
1149 daniel-mar 64
                "client_secret=".urlencode(OIDplus::baseConfig()->getValue('FACEBOOK_OAUTH2_CLIENT_SECRET'))."&".
65
                "code=".$_GET['code']
635 daniel-mar 66
);
1149 daniel-mar 67
 
68
if ($cont === false) {
69
        throw new OIDplusException(_L('Communication with %1 server failed', 'Facebook'));
70
}
71
 
635 daniel-mar 72
$data = json_decode($cont,true);
73
if (isset($data['error'])) {
74
        echo '<h2>Error at step 2</h2>';
75
        echo '<p>'.$data['error']['message'].'</p>';
76
        die();
77
}
78
$access_token = $data['access_token'];
79
 
80
// Get user infos
81
 
1149 daniel-mar 82
$cont = url_post_contents(
83
        "https://graph.facebook.com/v8.0/me?".
84
                "fields=id,email,name&".
85
                "access_token=".urlencode($access_token)
635 daniel-mar 86
);
1149 daniel-mar 87
 
88
if ($cont === false) {
89
        throw new OIDplusException(_L('Communication with %1 server failed', 'Facebook'));
90
}
91
 
635 daniel-mar 92
$data = json_decode($cont,true);
93
if (isset($data['error'])) {
94
        throw new OIDplusException(_L('Error receiving the authentication token from %1: %2','Facebook',$data['error']['message']));
95
}
96
$personal_name = $data['name'];
97
$email = !isset($data['email']) ? '' : $data['email'];
98
if (empty($email)) {
99
        throw new OIDplusException(_L('Your Facebook account does not have an email address.'));
100
}
101
 
102
// Everything's done! Now login and/or create account
103
 
705 daniel-mar 104
$ra = new OIDplusRA($email);
105
if (!$ra->existing()) {
106
        $ra->register_ra(null); // create a user account without password
635 daniel-mar 107
 
705 daniel-mar 108
        OIDplus::db()->query("update ###ra set ra_name = ?, personal_name = ? where email = ?", array($personal_name, $personal_name, $email));
635 daniel-mar 109
 
1267 daniel-mar 110
        OIDplus::logger()->log("V2:[INFO]RA(%1)", "RA '%1' was created because of successful Facebook OAuth2 login", $email);
705 daniel-mar 111
}
635 daniel-mar 112
 
1305 daniel-mar 113
OIDplus::authUtils()->raLoginEx($email, 'Facebook-OAuth2');
635 daniel-mar 114
 
705 daniel-mar 115
OIDplus::db()->query("UPDATE ###ra set last_login = ".OIDplus::db()->sqlDate()." where email = ?", array($email));
635 daniel-mar 116
 
705 daniel-mar 117
// Go back to OIDplus
635 daniel-mar 118
 
1406 daniel-mar 119
$loc = OIDplus::webpath(null,OIDplus::PATH_RELATIVE);
1005 daniel-mar 120
OIDplus::invoke_shutdown();
1406 daniel-mar 121
header('Location:'.$loc);