From f935ae988945f30819086484dea7834d2db2653b Mon Sep 17 00:00:00 2001 From: OlinetMacbookAir Date: Wed, 25 Jun 2025 19:30:57 +0200 Subject: [PATCH] Add Office365 User Permission --- AddOn/.DS_Store | Bin 0 -> 6148 bytes .../OutlookCalendar.php | 102 ++++++++++++++++++ AddOn/Calender_Office365_User/auth.php | 14 +++ AddOn/Calender_Office365_User/calendar.php | 56 ++++++++++ AddOn/Calender_Office365_User/callback.php | 69 ++++++++++++ AddOn/Calender_Office365_User/config.php | 11 ++ 6 files changed, 252 insertions(+) create mode 100644 AddOn/.DS_Store create mode 100644 AddOn/Calender_Office365_User/OutlookCalendar.php create mode 100644 AddOn/Calender_Office365_User/auth.php create mode 100644 AddOn/Calender_Office365_User/calendar.php create mode 100644 AddOn/Calender_Office365_User/callback.php create mode 100644 AddOn/Calender_Office365_User/config.php diff --git a/AddOn/.DS_Store b/AddOn/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..99e69f7d561adc77404b4a0513a525910b0a955b GIT binary patch literal 6148 zcmeHK&2G~`5T0#A>rf$bpd#XAiEDv0Ndr|cZW<0qAOz;;04T(%g}^ks1Xg0u`cYN1FY1XLrWl&$GK;B4X`vxJy(aA_pq5bP>f5MD|Nv zk~L!~1DT4!DWr%-)TM_@qpiU*U>W$=7?5kXN=MYA1S|LS`aPy&im4B4gIctQHGPQH zox;ZNC88fBB7m>lI1ZsVzbQeD=;|-VdrFzyEf%A(+lX-I_oD@qY-rx?b1+QeEU(qR zvbFWng^f*T)7f%f`6puH=e>NKwR@u%vh_rWB$(HG!LvA;bSqbm1kZahk4DNN4kHYC z`8?*Kn6$;1hne#Ab%#@S%H2wJI<2>AJ8q-7KihGq`*qZtjn-^dcDAqII(XcDlcZd{ zQ!Ej~o~h)L!8yD~Wkn8?!LHvI>2Mxm^$4lxbPR9Khx+A@&5bYeyRP^isR+*?%JAe* zXYstma182{G+#g)1M9*NMQEeS4)D-|&f>{ab@|QsRxCT9gg+}y1 zn05tfS7xplOuNJGnsJ`NLZfykW-cGhJeipr3R6!pDi;*yI93&T6jz~2(C5ku W&@)(Qgau-M1QZRnunhcF2EGFrQ^IHf literal 0 HcmV?d00001 diff --git a/AddOn/Calender_Office365_User/OutlookCalendar.php b/AddOn/Calender_Office365_User/OutlookCalendar.php new file mode 100644 index 00000000..c0661afe --- /dev/null +++ b/AddOn/Calender_Office365_User/OutlookCalendar.php @@ -0,0 +1,102 @@ +clientId = $clientId; + $this->clientSecret = $clientSecret; + $this->redirectUri = $redirectUri; + $this->accessToken = $accessToken; + $this->refreshToken = $refreshToken; + } + + // ------------------------------------------ + // 🔁 Refresh Token verwenden + public function refreshAccessToken() { + $url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"; + + $data = [ + 'grant_type' => 'refresh_token', + 'refresh_token' => $this->refreshToken, + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'redirect_uri' => $this->redirectUri, + 'scope' => 'https://graph.microsoft.com/.default' + ]; + + $response = $this->sendRequest($url, $data, true); + if (isset($response['access_token'])) { + $this->accessToken = $response['access_token']; + $this->refreshToken = $response['refresh_token'] ?? $this->refreshToken; + } + + return $response; + } + + // ------------------------------------------ + // 📅 Termin erstellen + public function createEvent($eventData) { + $url = "https://graph.microsoft.com/v1.0/me/events"; + return $this->sendRequest($url, $eventData, false, 'POST'); + } + + // ✏️ Termin bearbeiten + public function updateEvent($eventId, $eventData) { + $url = "https://graph.microsoft.com/v1.0/me/events/{$eventId}"; + return $this->sendRequest($url, $eventData, false, 'PATCH'); + } + + // ❌ Termin löschen + public function deleteEvent($eventId) { + $url = "https://graph.microsoft.com/v1.0/me/events/{$eventId}"; + return $this->sendRequest($url, [], false, 'DELETE'); + } + + // ------------------------------------------ + // 🔧 API Request senden (intern) + private function sendRequest($url, $data = [], $isForm = false, $method = 'POST') { + $ch = curl_init($url); + $headers = [ + 'Authorization: Bearer ' . $this->accessToken, + ]; + + if ($isForm) { + $body = http_build_query($data); + $headers[] = 'Content-Type: application/x-www-form-urlencoded'; + } else { + $body = json_encode($data); + $headers[] = 'Content-Type: application/json'; + } + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + if ($method !== 'GET' && !empty($data)) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + + $response = curl_exec($ch); + $err = curl_error($ch); + curl_close($ch); + + if ($err) { + return ['error' => $err]; + } + + return json_decode($response, true); + } + + // 🔓 Getter für AccessToken + public function getAccessToken() { + return $this->accessToken; + } + + public function getRefreshToken() { + return $this->refreshToken; + } +} diff --git a/AddOn/Calender_Office365_User/auth.php b/AddOn/Calender_Office365_User/auth.php new file mode 100644 index 00000000..6b8814cd --- /dev/null +++ b/AddOn/Calender_Office365_User/auth.php @@ -0,0 +1,14 @@ + $config['client_id'], + 'response_type' => 'code', + 'redirect_uri' => $config['redirect_uri'], + 'response_mode' => 'query', + 'scope' => $config['scopes'], +]; + +$authUrl = $config['auth_url'] . '?' . http_build_query($params); +header("Location: $authUrl"); +exit; diff --git a/AddOn/Calender_Office365_User/calendar.php b/AddOn/Calender_Office365_User/calendar.php new file mode 100644 index 00000000..e7216c17 --- /dev/null +++ b/AddOn/Calender_Office365_User/calendar.php @@ -0,0 +1,56 @@ + ($data['time_saved'] + $data['expires_in'] - 60)) { + $calendar->refreshAccessToken(); + $tokens[$email]['access_token'] = $calendar->getAccessToken(); + $tokens[$email]['refresh_token'] = $calendar->getRefreshToken(); + $tokens[$email]['time_saved'] = time(); + file_put_contents($config['token_storage'], json_encode($tokens, JSON_PRETTY_PRINT)); +} + +// ➤ Beispiel: Termin anlegen +$event = [ + "subject" => "Test-Meeting via PHP", + "start" => [ + "dateTime" => "2025-06-25T10:00:00", + "timeZone" => "Europe/Berlin" + ], + "end" => [ + "dateTime" => "2025-06-25T11:00:00", + "timeZone" => "Europe/Berlin" + ], + "body" => [ + "contentType" => "HTML", + "content" => "Meeting von OutlookCalendar PHP" + ] +]; + +$response = $calendar->createEvent($event); + +echo "
";
+print_r($response);
+echo "
"; diff --git a/AddOn/Calender_Office365_User/callback.php b/AddOn/Calender_Office365_User/callback.php new file mode 100644 index 00000000..11598156 --- /dev/null +++ b/AddOn/Calender_Office365_User/callback.php @@ -0,0 +1,69 @@ + $config['client_id'], + 'scope' => $config['scopes'], + 'code' => $code, + 'redirect_uri' => $config['redirect_uri'], + 'grant_type' => 'authorization_code', + 'client_secret' => $config['client_secret'], +]; + +$ch = curl_init($config['token_url']); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); +curl_setopt($ch, CURLOPT_POST, true); +curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/x-www-form-urlencoded', +]); + +$response = curl_exec($ch); +curl_close($ch); + +$tokenData = json_decode($response, true); + +if (!isset($tokenData['access_token'])) { + die("Fehler beim Token-Abruf: " . $response); +} + +// ➤ E-Mail-Adresse vom User holen +$ch = curl_init($config['graph_url'] . '/me'); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $tokenData['access_token'], +]); +$userResponse = curl_exec($ch); +curl_close($ch); + +$userData = json_decode($userResponse, true); +$email = $userData['mail'] ?? $userData['userPrincipalName'] ?? null; + +if (!$email) { + die("Fehler beim Abrufen der E-Mail."); +} + +// ➤ Speichern in tokens.json +$tokens = []; +if (file_exists($config['token_storage'])) { + $tokens = json_decode(file_get_contents($config['token_storage']), true); +} + +$tokens[$email] = [ + 'access_token' => $tokenData['access_token'], + 'refresh_token' => $tokenData['refresh_token'], + 'expires_in' => $tokenData['expires_in'], + 'time_saved' => time() +]; + +file_put_contents($config['token_storage'], json_encode($tokens, JSON_PRETTY_PRINT)); + +echo "Erfolgreich verbunden mit: $email
"; +echo "Zum Kalender-Tool"; diff --git a/AddOn/Calender_Office365_User/config.php b/AddOn/Calender_Office365_User/config.php new file mode 100644 index 00000000..5003cd24 --- /dev/null +++ b/AddOn/Calender_Office365_User/config.php @@ -0,0 +1,11 @@ + '', + 'client_secret' => '', + 'redirect_uri' => 'https://servicebericht.isgus.de/calsync/callback.php', + 'scopes' => 'offline_access user.read calendars.readwrite', + 'auth_url' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', + 'token_url' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token', + 'graph_url' => 'https://graph.microsoft.com/v1.0', + 'token_storage' => __DIR__ . '/tokens.json', +];