├── .gitignore ├── README.md ├── autoload.php ├── composer.json ├── example.php └── theCodingCompany ├── HttpRequest.php ├── Mastodon.php └── oAuth.php /.gitignore: -------------------------------------------------------------------------------- 1 | test_code.php 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MastodonOAuthPHP 2 | PHP Library for Mastodon REST API 3 | 4 | ## What's in it? 5 | 6 | * App creation. 7 | * Full oAuth implementation to authorize your App by users. 8 | * Create and get authorization token, access token, client_id, client_secret and bearer token. 9 | * Authenticate users 10 | * Get user information 11 | * Get user followers and following 12 | * Get user status 13 | * Post status update 14 | 15 | 16 | ## Installation using Composer 17 | 18 | ``` 19 | composer require thecodingcompany/php-mastodon 20 | ``` 21 | 22 | ## Questions and example? 23 | 24 | Yes, mail me at: vangelier at hotmail dot com 25 | Contact me on #Twitter @digital_human 26 | Contact me on #Mastodon https://mastodon.social/@digitalhuman 27 | 28 | ## Get started 29 | 30 | ### Step 1 31 | 32 | First step is you need to create a so called App. This app represents your 'service'. With this app you provide services to users or use Mastodon for other reasons. 33 | 34 | To create an App is as simple as: 35 | 36 | ``` 37 | 43 | * @version 1.0 44 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 45 | * 46 | */ 47 | require_once("autoload.php"); 48 | 49 | $t = new \theCodingCompany\Mastodon(); 50 | 51 | /** 52 | * Create a new App and get the client_id and client_secret 53 | */ 54 | $token_info = $t->createApp("MyCoolAppName", "http://www.internet.com"); 55 | 56 | $serializedData = serialize($token_info); 57 | 58 | // save the special tokens to a file, so you don't lose them 59 | file_put_contents('mastodon_creds', $serializedData); // this will save it in the same folder as this file 60 | ?> 61 | ``` 62 | 63 | The parameter ```$token_info``` now has your 'client_id' and 'client_secret'. This information is important for the rest of your life ;). Store it in a file, DB or array. You need this everytime you communicate with Mastodon. 64 | 65 | ### Step 2 66 | 67 | Now you (your app) wants to provide services to a user. For this the user needs to authorize your app. Else you can't help him/her. To do this you need to redirect the user, with your tokens to Mastodon and ask for permission so to say. And example: 68 | 69 | ``` 70 | 76 | * @version 1.0 77 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 78 | * 79 | */ 80 | require_once("autoload.php"); 81 | 82 | $recoveredData = file_get_contents('mastodon_creds'); 83 | 84 | // unserializing to get actual array 85 | $recoveredArray = unserialize($recoveredData); 86 | 87 | $t = new \theCodingCompany\Mastodon(); 88 | 89 | /** 90 | * We now have a client_id and client_secret. Set the domain and provide the library with your App's client_id and secret. 91 | */ 92 | $t->setMastodonDomain("mastodon.social"); // Set the mastodon domain, you can remove this line if you're using mastodon.social as it's the default 93 | 94 | $t->setCredentials($recoveredArray); // use the keys from the file we stored in Step 1 95 | 96 | /** 97 | * Now that is set we can get the Authorization URL and redirect the user to Mastodon 98 | * After the user approves your App, it will return with an Access Token. 99 | */ 100 | $auth_url = $t->getAuthUrl(); 101 | header("Location: {$auth_url}", true); 102 | exit; 103 | 104 | ``` 105 | 106 | ### Step 3 107 | 108 | So you now have 3 tokens. The client_id, client_secret and the users access_token. Now exchange the access token for a bearer token and you are done. Save these tokens! 109 | 110 | ``` 111 | 117 | * @version 1.0 118 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 119 | * 120 | */ 121 | require_once("autoload.php"); 122 | 123 | $recoveredData = file_get_contents('mastodon_creds'); 124 | 125 | // unserializing to get actual array 126 | $recoveredArray = unserialize($recoveredData); 127 | 128 | $t = new \theCodingCompany\Mastodon(); 129 | 130 | /** 131 | * We now have a client_id and client_secret. Set the domain and provide the library with your App's client_id and secret. 132 | */ 133 | $t->setMastodonDomain("mastodon.social"); // Set the mastodon domain, you can remove this line if you're using mastodon.social as it's the default 134 | 135 | $t->setCredentials(recoveredArray); // use the keys from the file we stored in Step 1 136 | 137 | $token_info = $t->getAccessToken("7c47d0c636314a1dff21reryyy5edf91884856dc0f78148f848d475136"); //The access token you received in step 2 from the user. 138 | 139 | /** 140 | * The above '$token_info' will now give you a bearer token (If successfull), you also need to store that and keep it safe! 141 | * 142 | */ 143 | ``` 144 | 145 | ## Step 4 146 | 147 | To then post a status, you just do this: 148 | 149 | ``` 150 | require_once("autoload.php"); 151 | 152 | $t = new \theCodingCompany\Mastodon(); 153 | 154 | $t->setMastodonDomain(website address); // change this to whatever Mastodon instance you're using, or remove it entirely if you're using mastodon.social (as it's the default) 155 | 156 | $t->setCredentials($credentials); // where $credentials are your "client_id", "client_secret" and "bearer" in the form of an array with those exact names (from what you got in the earlier steps) 157 | 158 | $t->postStatus('API Test - PLZ ignore <3'); 159 | ``` 160 | 161 | ## Full code overview options etc 162 | 163 | ``` 164 | 170 | * @version 1.0 171 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 172 | * 173 | */ 174 | require_once("autoload.php"); 175 | 176 | $t = new \theCodingCompany\Mastodon(); 177 | 178 | /** 179 | * Create a new App and get the client_id and client_secret 180 | */ 181 | $token_info = $t->createApp("MyCoolAppName", "http://www.internet.com"); 182 | 183 | 184 | //Get the authorization url 185 | $auth_url = $t->getAuthUrl(); 186 | /* 187 | * 1) Send the above URL '$auth_url' to the user. The need to authorize your App. 188 | * 2) When they authorized your app, they will receive a token. The authorization token. 189 | * 3) Put the authorization token in the request below to exchange it for a bearer token. 190 | */ 191 | 192 | //Request the bearer token 193 | $token_info = $t->getAccessToken("7c47d0c636314a1dff21reryyy5edf91884856dc0f78148f848d475136"); 194 | 195 | /** 196 | * The above '$token_info' will now be an array with the info like below. (If successfull) 197 | * No these are not real, your right. 198 | * 199 | { 200 | "client_id": "87885c2bf1a9d9845345345318d1eeeb1e48bb676aa747d3216adb96f07", 201 | "client_secret": "a1284899df5250bd345345f5fb971a5af5c520ca2c3e4ce10c203f81c6", 202 | "bearer": "77e0daa7f252941ae8343543653454f4de8ca7ae087caec4ba85a363d5e08de0d" 203 | } 204 | */ 205 | 206 | /** 207 | * Authenticate a user by username and password and receive the bearer token 208 | */ 209 | $bearer_token = $t->authUser("vangelier@hotmail.com", "MySecretP@ssW0rd"); 210 | 211 | /** 212 | * Get the userinfo by authentication 213 | */ 214 | 215 | $user_info = $t->getUser("vangelier@hotmail.com", "MySecretP@ssW0rd"); 216 | 217 | /** 218 | * Get user followers / following 219 | */ 220 | $followers = $t->authenticate("vangelier@hotmail.com", "MySecretP@ssW0rd") 221 | ->getFollowers(); 222 | 223 | /** 224 | * Get user statusses 225 | */ 226 | $statusses = $t->authenticate("vangelier@hotmail.com", "MySecretP@ssW0rd") 227 | ->getStatuses(); 228 | 229 | 230 | /** 231 | * Post status update 232 | */ 233 | 234 | $status = $t->authenticate("vangelier@hotmail.com", "MySecretP@ssW0rd") 235 | ->postStatus("Text status update"); 236 | 237 | ``` 238 | -------------------------------------------------------------------------------- /autoload.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 9 | * 10 | */ 11 | define('CLASS_DIR', __DIR__); 12 | set_include_path(get_include_path().PATH_SEPARATOR.CLASS_DIR); 13 | 14 | spl_autoload_register(function($name){ 15 | //For namespaces we replace \ with / to correct the Path 16 | $filename = str_replace("\\", "/", $name); 17 | require_once "{$filename}.php"; 18 | }); -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thecodingcompany/php-mastodon", 3 | "type": "library", 4 | "description": "Mastodon PHP library oAuth and API", 5 | "keywords": ["php","mastodon","api","oauth"], 6 | "homepage": "https://github.com/TheCodingCompany/MastodonOAuthPHP", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Victor Angelier", 11 | "email": "vangelier@hotmail.com", 12 | "homepage": "https://www.thecodingcompany.se", 13 | "role": "Founder" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=5.6.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "theCodingCompany\\": "theCodingCompany/" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 9 | * 10 | */ 11 | require_once("autoload.php"); 12 | 13 | $t = new \theCodingCompany\Mastodon(); 14 | 15 | /** 16 | * Create a new App and get the client_id and client_secret 17 | */ 18 | $token_info = $t->createApp("MyCoolAppName", "http://www.internet.com"); 19 | 20 | 21 | //Get the authorization url 22 | $auth_url = $t->getAuthUrl(); 23 | /* 24 | * 1) Send the above URL '$auth_url' to the user. The need to authorize your App. 25 | * 2) When they authorized your app, they will receive a token. The authorization token. 26 | * 3) Put the authorization token in the request below to exchange it for a bearer token. 27 | */ 28 | 29 | //Request the bearer token 30 | $token_info = $t->getAccessToken("7c47d0c636314a1dff21reryyy5edf91884856dc0f78148f848d475136"); 31 | 32 | /** 33 | * The above '$token_info' will now be an array with the info like below. (If successfull) 34 | * No these are not real, your right. 35 | * 36 | { 37 | "client_id": "87885c2bf1a9d9845345345318d1eeeb1e48bb676aa747d3216adb96f07", 38 | "client_secret": "a1284899df5250bd345345f5fb971a5af5c520ca2c3e4ce10c203f81c6", 39 | "bearer": "77e0daa7f252941ae8343543653454f4de8ca7ae087caec4ba85a363d5e08de0d" 40 | } 41 | */ 42 | 43 | /** 44 | * Authenticate a user by username and password and receive the bearer token 45 | */ 46 | $bearer_token = $t->authUser("vangelier@hotmail.com", "MySecretP@ssW0rd"); 47 | 48 | /** 49 | * Get the userinfo by authentication 50 | */ 51 | 52 | $user_info = $t->getUser("vangelier@hotmail.com", "MySecretP@ssW0rd"); 53 | 54 | /** 55 | * Get user followers / following 56 | */ 57 | $followers = $t->authenticate("vangelier@hotmail.com", "MySecretP@ssW0rd") 58 | ->getFollowers(); 59 | 60 | /** 61 | * Get user statusses 62 | */ 63 | $statusses = $t->authenticate("vangelier@hotmail.com", "MySecretP@ssW0rd") 64 | ->getStatuses(); 65 | 66 | -------------------------------------------------------------------------------- /theCodingCompany/HttpRequest.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 9 | * 10 | */ 11 | namespace theCodingCompany; 12 | 13 | /** 14 | * HTTP Request object finetune for High Security 15 | */ 16 | final class HttpRequest 17 | { 18 | /** 19 | * Holds our base path. In most cases this is just /, but it can be /api for example 20 | * @var string 21 | */ 22 | private static $base_path = "/"; 23 | 24 | /** 25 | * Base URL without leading / 26 | * @var string 27 | */ 28 | private static $base_url = ""; 29 | 30 | /** 31 | * Holds our instance 32 | * @var array 33 | */ 34 | private static $instance = array(); 35 | 36 | /** 37 | * Enable debugging 38 | * @var bool 39 | */ 40 | private static $debug = false; 41 | 42 | /** 43 | * Construct new HttpRequest 44 | * @param string $base_url Base url like http://api.website.com without leading / 45 | * @param string $base_path Base path like, / or /api 46 | */ 47 | protected function __construct($base_url = "", $base_path = "/") { 48 | self::$base_path = $base_path; 49 | self::$base_url = $base_url; 50 | } 51 | protected function __clone(){} 52 | protected function __wakeup(){} 53 | 54 | /** 55 | * Singleton design pattern 56 | * @param string $base_url The full FQDN url. http://api.domainname.com 57 | * @param string $base_path The endpoint. We start at / 58 | * @return HttpRequest instance 59 | */ 60 | public static function Instance($base_url = "", $base_path = "/"){ 61 | $cls = get_called_class(); 62 | if(!isset(self::$instance[$cls])){ 63 | self::$instance[$cls] = new HttpRequest($base_url, $base_path); 64 | } 65 | return self::$instance[$cls]; 66 | } 67 | 68 | /** 69 | * HTTP POST request 70 | * @param string $path 71 | * @param array $parameters 72 | * @param array $headers 73 | * @return bool 74 | */ 75 | public static function Post($path = "", $parameters = array(), $headers = array()){ 76 | //Sen the request and return response 77 | $post_data = json_encode($parameters); 78 | return self::http_request( 79 | "POST", 80 | self::$base_url.self::$base_path.$path, 81 | $headers, 82 | $post_data 83 | ); 84 | } 85 | 86 | /** 87 | * HTTP GET request 88 | * @param string $path 89 | * @param array $parameters 90 | * @param array $headers 91 | * @return bool 92 | */ 93 | public static function Get($path = "", $parameters = array(), $headers = array()){ 94 | //Sen the request and return response 95 | return self::http_request( 96 | "GET", 97 | self::$base_url.self::$base_path.$path, 98 | $headers, 99 | $parameters 100 | ); 101 | } 102 | 103 | /** 104 | * Buikd the HTTP request 105 | * @param string $method GET|POST 106 | * @param string $url 107 | * @param array $headers 108 | * @param array $parameters 109 | * @return boolean 110 | */ 111 | private static function http_request($method = "GET", $url = "", $headers = array(), $parameters = array()) { 112 | 113 | //HTTP request options 114 | $opts = array( 115 | 'http' => array( 116 | 'method' => $method, 117 | 'header' => '', 118 | 'content' => '', 119 | 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)', 120 | 'timeout' => 30, 121 | 'protocol_version' => 1.1 122 | ), 123 | 'ssl' => array( 124 | 'verify_peer' => false, 125 | 'verify_host' => false, 126 | 'ciphers' => 'HIGH' 127 | ) 128 | ); 129 | 130 | //Check if we have parameters to post 131 | if (count($parameters) > 0 && is_array($parameters)) { 132 | $content = ""; 133 | foreach($parameters as $k => $v) { 134 | $content .= "&".urlencode($k)."=" . urlencode($v); 135 | } 136 | 137 | // Strip first & sign 138 | $content = substr($content, 1); 139 | 140 | // If the method is get, append to the URL 141 | if ($method == "GET") { 142 | $url .= "?" . $content; 143 | } 144 | // Otherwise, post in the content 145 | else { 146 | //Strip first & sign 147 | $opts["http"]["content"] = $content; 148 | } 149 | } 150 | elseif ($parameters) { 151 | //Send as is 152 | $opts["http"]["content"] = $parameters; 153 | } 154 | 155 | //Check if we have headers to parse 156 | if (count($headers) > 0 && is_array($headers)) { 157 | $content = ""; 158 | foreach ($headers as $k => $v) { 159 | $content .= "{$k}: {$v}\r\n"; 160 | } 161 | //Strip first & sign 162 | $opts["http"]["header"] = trim($content); 163 | } 164 | if ($opts["http"]["header"] === "") { 165 | unset($opts["http"]["header"]); 166 | } 167 | 168 | //Debug 169 | if (self::$debug) { 170 | echo "
" . print_r($opts, true) . ""; 171 | echo $url . "
" . print_r(error_get_last(), true) . ""; 185 | $error .= "
" . print_r($response, true) . ""; 186 | 187 | if(self::$debug){ print_r($error); } 188 | return $error; 189 | } 190 | else{ 191 | 192 | //Debug the response/url 193 | self::debug_response($url, $context); 194 | 195 | if (($json = \json_decode($response, true)) !== NULL) { 196 | return $json; 197 | } 198 | else { 199 | return $response; 200 | } 201 | } 202 | } 203 | 204 | /** 205 | * Debug method for response analyzing 206 | * @param string $url 207 | * @param resource $context 208 | */ 209 | private static function debug_response($url, $context){ 210 | //Get and debug headers 211 | if(self::$debug){ 212 | //Get meta data for debugging 213 | $fp = @fopen($url, "r", false, $context); 214 | if($fp){ 215 | $req_headers = stream_get_meta_data($fp); 216 | if(isset($req_headers["wrapper_data"])){ 217 | echo "
".print_r($req_headers["wrapper_data"], true).""; 218 | }else{ 219 | echo "
".print_r($req_headers, true).""; 220 | } 221 | } 222 | echo "
Check host alive headers"; 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /theCodingCompany/Mastodon.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 9 | * 10 | */ 11 | namespace theCodingCompany; 12 | 13 | use \theCodingCompany\HttpRequest; 14 | 15 | /** 16 | * Mastodon main class 17 | */ 18 | class Mastodon 19 | { 20 | //Mastodon oAuth 21 | use \theCodingCompany\oAuth; 22 | 23 | /** 24 | * Holds our current user_id for :id in API calls 25 | * @var string 26 | */ 27 | private $mastodon_user_id = null; 28 | 29 | /** 30 | * Holds our current userinfo 31 | * @var array 32 | */ 33 | private $mastodon_userinfo = null; 34 | 35 | /** 36 | * Construct new Mastodon class 37 | */ 38 | public function __construct($domainname = "mastodon.social") { 39 | 40 | //Set the domain name to use 41 | $this->setMastodonDomain($domainname); 42 | } 43 | 44 | /** 45 | * Create an App and get client_id and client_secret 46 | * @param string $name 47 | * @param string $website_url 48 | * @return array|bool 49 | */ 50 | public function createApp($name, $website_url){ 51 | if(!empty($name) && !empty($website_url)){ 52 | 53 | //Set our info 54 | $this->app_config["client_name"] = $name; 55 | $this->app_config["website"] = $website_url; 56 | 57 | return $this->getAppConfig(); 58 | } 59 | return false; 60 | } 61 | 62 | /** 63 | * Authenticate the user 64 | * @param string $username 65 | * @param string $password 66 | * @return $this 67 | */ 68 | public function authenticate($username = null, $password = null) { 69 | $this->authUser($username, $password); 70 | 71 | //Set current working userid 72 | $this->mastodon_userinfo = $this->getUser(); 73 | 74 | return $this; //For method chaining 75 | } 76 | 77 | /** 78 | * Post a new status to your {visibility} timeline 79 | * @param string $text 80 | * @param string $visibility 81 | * @return HttpRequest | bool 82 | */ 83 | public function postStatus($text = "", $visibility = "public", $in_reply_to_id = null){ 84 | if(!empty($this->getCredentials())){ 85 | 86 | $headers = $this->getHeaders(); 87 | 88 | //Create our object 89 | $http = HttpRequest::Instance($this->getApiURL()); 90 | $status = $http::Post( 91 | "api/v1/statuses", 92 | array( 93 | "status" => $text, 94 | "visibility" => $visibility, 95 | "in_reply_to_id" => $in_reply_to_id 96 | ), 97 | $headers 98 | ); 99 | return $status; 100 | } 101 | return false; 102 | } 103 | 104 | /** 105 | * Get mastodon user 106 | */ 107 | public function getUser(){ 108 | if(empty($this->mastodon_userinfo)){ 109 | //Create our object 110 | $http = HttpRequest::Instance($this->getApiURL()); 111 | $user_info = $http::Get( 112 | "api/v1/accounts/verify_credentials", 113 | null, 114 | $this->getHeaders() 115 | ); 116 | if(is_array($user_info) && isset($user_info["username"])){ 117 | $this->mastodon_user_id = (int)$user_info["id"]; 118 | return $user_info; 119 | }else{ 120 | echo "Authentication or authorization failed\r\n"; 121 | } 122 | } 123 | return $this->mastodon_userinfo; 124 | } 125 | 126 | /** 127 | * Get current user's followers 128 | */ 129 | public function getFollowers(){ 130 | if($this->mastodon_user_id > 0){ 131 | 132 | //Create our object 133 | $http = HttpRequest::Instance($this->getApiURL()); 134 | $accounts = $http::Get( 135 | "api/v1/accounts/{$this->mastodon_user_id}/followers", 136 | null, 137 | $this->getHeaders() 138 | ); 139 | if(is_array($accounts) && count($accounts) > 0){ 140 | return $accounts; 141 | } 142 | 143 | } 144 | return false; 145 | } 146 | 147 | /** 148 | * Get current user's following 149 | */ 150 | public function getFollowing(){ 151 | if($this->mastodon_user_id > 0){ 152 | 153 | //Create our object 154 | $http = HttpRequest::Instance($this->getApiURL()); 155 | $accounts = $http::Get( 156 | "api/v1/accounts/{$this->mastodon_user_id}/following", 157 | null, 158 | $this->getHeaders() 159 | ); 160 | if(is_array($accounts) && count($accounts) > 0){ 161 | return $accounts; 162 | } 163 | 164 | } 165 | return false; 166 | } 167 | 168 | /** 169 | * Get current user's statuses 170 | */ 171 | public function getStatuses(){ 172 | if($this->mastodon_user_id > 0){ 173 | 174 | //Create our object 175 | $http = HttpRequest::Instance($this->getApiURL()); 176 | $statusses = $http::Get( 177 | "api/v1/accounts/{$this->mastodon_user_id}/statuses", 178 | null, 179 | $this->getHeaders() 180 | ); 181 | if(is_array($statusses) && count($statusses) > 0){ 182 | return $statusses; 183 | } 184 | 185 | } 186 | return false; 187 | } 188 | 189 | /** 190 | * Get current user's notifications. If $since_id is provided, will only get the items 191 | * after since_id. 192 | * 193 | */ 194 | public function getNotifications($since_id = null){ 195 | if($this->mastodon_user_id > 0){ 196 | 197 | //Create our object 198 | $http = HttpRequest::Instance($this->getApiURL()); 199 | 200 | $notifications = $http::Get( 201 | "api/v1/notifications", 202 | ($since_id != null ? array('since_id'=>$since_id) : null), 203 | $this->getHeaders() 204 | ); 205 | 206 | if(is_array($notifications) && count($notifications) > 0){ 207 | return $notifications; 208 | } 209 | } 210 | return false; 211 | } 212 | 213 | /** 214 | * Clears the user's notifications. Returns true if successful. 215 | * 216 | */ 217 | public function clearNotifications(){ 218 | if($this->mastodon_user_id > 0){ 219 | 220 | //Create our object 221 | $http = HttpRequest::Instance($this->getApiURL()); 222 | 223 | $clear_result = $http::Post( 224 | "api/v1/notifications/clear", 225 | null, 226 | $this->getHeaders() 227 | ); 228 | 229 | if(is_array($clear_result)) { 230 | return true; 231 | } 232 | else { 233 | return false; 234 | } 235 | } 236 | return false; 237 | } 238 | 239 | } 240 | -------------------------------------------------------------------------------- /theCodingCompany/oAuth.php: -------------------------------------------------------------------------------- 1 | 7 | * @version 1.0 8 | * @license http://www.apache.org/licenses/GPL-compatibility.html GPL 9 | * 10 | */ 11 | namespace theCodingCompany; 12 | 13 | use theCodingCompany\HttpRequest; 14 | 15 | /** 16 | * oAuth class for use at Mastodon 17 | */ 18 | trait oAuth 19 | { 20 | 21 | /** 22 | * Our API to use 23 | * @var string 24 | */ 25 | private $mastodon_api_url = "mastodon.social"; 26 | 27 | /** 28 | * Default headers for each request 29 | * @var array 30 | */ 31 | private $headers = array( 32 | "Content-Type" => "application/json; charset=utf-8", 33 | "Accept" => "*/*" 34 | ); 35 | 36 | /** 37 | * Holds our client_id and secret 38 | * @var array 39 | */ 40 | private $credentials = array( 41 | "client_id" => "", 42 | "client_secret" => "", 43 | "bearer" => "" 44 | ); 45 | 46 | /** 47 | * App config 48 | * @var array 49 | */ 50 | private $app_config = array( 51 | "client_name" => "MastoTweet", 52 | "redirect_uris" => "urn:ietf:wg:oauth:2.0:oob", 53 | "scopes" => "read write", 54 | "website" => "https://www.thecodingcompany.se" 55 | ); 56 | 57 | /** 58 | * Set credentials 59 | * @var array 60 | **/ 61 | public function setCredentials(array $credentials) 62 | { 63 | $this->credentials = $credentials; 64 | } 65 | 66 | /** 67 | * Set credentials 68 | * @return array 69 | **/ 70 | public function getCredentials() 71 | { 72 | return $this->credentials; 73 | } 74 | 75 | /** 76 | * Get the API endpoint 77 | * @return string 78 | */ 79 | public function getApiURL(){ 80 | return "https://{$this->mastodon_api_url}"; 81 | } 82 | 83 | /** 84 | * Get Request headers 85 | * @return array 86 | */ 87 | public function getHeaders(){ 88 | if(isset($this->credentials["bearer"])){ 89 | $this->headers["Authorization"] = "Bearer {$this->credentials["bearer"]}"; 90 | } 91 | return $this->headers; 92 | } 93 | 94 | /** 95 | * Start at getting or creating app 96 | */ 97 | public function getAppConfig(){ 98 | //Get singleton instance 99 | $http = HttpRequest::Instance("https://{$this->mastodon_api_url}"); 100 | $config = $http::post( 101 | "api/v1/apps", //Endpoint 102 | $this->app_config, 103 | $this->headers 104 | ); 105 | //Check and set our credentials 106 | if(!empty($config) && isset($config["client_id"]) && isset($config["client_secret"])){ 107 | $this->credentials['client_id'] = $config['client_id']; 108 | $this->credentials['client_secret'] = $config['client_secret']; 109 | return $this->credentials; 110 | }else{ 111 | return false; 112 | } 113 | } 114 | 115 | /** 116 | * Set the correct domain name 117 | * @param string $domainname 118 | */ 119 | public function setMastodonDomain($domainname = ""){ 120 | if(!empty($domainname)){ 121 | $this->mastodon_api_url = $domainname; 122 | } 123 | } 124 | 125 | /** 126 | * Create authorization url 127 | */ 128 | public function getAuthUrl(){ 129 | if(is_array($this->credentials) && isset($this->credentials["client_id"])){ 130 | 131 | //Return the Authorization URL 132 | return "https://{$this->mastodon_api_url}/oauth/authorize/?".http_build_query(array( 133 | "response_type" => "code", 134 | "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob", 135 | "scope" => "read write", 136 | "client_id" => $this->credentials["client_id"] 137 | )); 138 | } 139 | return false; 140 | } 141 | 142 | /** 143 | * Handle our bearer token info 144 | * @param array $token_info 145 | * @return string | boolean 146 | */ 147 | private function _handle_bearer($token_info = null){ 148 | if(!empty($token_info) && isset($token_info["access_token"])){ 149 | 150 | //Add to our credentials 151 | $this->credentials["bearer"] = $token_info["access_token"]; 152 | 153 | return $token_info["access_token"]; 154 | } 155 | return false; 156 | } 157 | 158 | /** 159 | * Get access token 160 | * @param string $auth_code 161 | * @return string | bool 162 | */ 163 | public function getAccessToken($auth_code = ""){ 164 | 165 | if(is_array($this->credentials) && isset($this->credentials["client_id"])){ 166 | 167 | //Request access token in exchange for our Authorization token 168 | $http = HttpRequest::Instance("https://{$this->mastodon_api_url}"); 169 | $token_info = $http::Post( 170 | "oauth/token", 171 | array( 172 | "grant_type" => "authorization_code", 173 | "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob", 174 | "client_id" => $this->credentials["client_id"], 175 | "client_secret" => $this->credentials["client_secret"], 176 | "code" => $auth_code 177 | ), 178 | $this->headers 179 | ); 180 | 181 | //Save our token info 182 | return $this->_handle_bearer($token_info); 183 | } 184 | return false; 185 | } 186 | 187 | /** 188 | * Authenticate a user by username and password 189 | * @param string $username usernam@domainname.com 190 | * @param string $password The password 191 | * @return bool 192 | */ 193 | private function authUser($username = null, $password = null){ 194 | if(!empty($username) && stristr($username, "@") !== FALSE && !empty($password)){ 195 | 196 | 197 | if(is_array($this->credentials) && isset($this->credentials["client_id"])){ 198 | 199 | //Request access token in exchange for our Authorization token 200 | $http = HttpRequest::Instance("https://{$this->mastodon_api_url}"); 201 | $token_info = $http::Post( 202 | "oauth/token", 203 | array( 204 | "grant_type" => "password", 205 | "client_id" => $this->credentials["client_id"], 206 | "client_secret" => $this->credentials["client_secret"], 207 | "username" => $username, 208 | "password" => $password, 209 | "scope" => "read write" 210 | ), 211 | $this->headers 212 | ); 213 | 214 | return $this->credentials["bearer"] = $token_info["access_token"]; 215 | } 216 | } 217 | return false; 218 | } 219 | } 220 | --------------------------------------------------------------------------------
\r\n"; 223 | $headers = @get_headers($url); 224 | if($headers !== FALSE){ 225 | print_r($headers); 226 | } 227 | echo "