From bce30d7b61770dffd2d9a2b0883f81aa3f90d33e Mon Sep 17 00:00:00 2001 From: alphayax Date: Tue, 2 Feb 2016 20:34:57 +0100 Subject: [PATCH] Initial commit --- freebox/api/v3/Service.php | 41 ++++++++++ freebox/api/v3/dhcp/DHCP.php | 48 +++++++++++ freebox/api/v3/login/Authorize.php | 125 +++++++++++++++++++++++++++++ freebox/api/v3/login/Login.php | 70 ++++++++++++++++ freebox/utils/Application.php | 122 ++++++++++++++++++++++++++++ freebox/utils/RestAuth.php | 54 +++++++++++++ 6 files changed, 460 insertions(+) create mode 100644 freebox/api/v3/Service.php create mode 100644 freebox/api/v3/dhcp/DHCP.php create mode 100644 freebox/api/v3/login/Authorize.php create mode 100644 freebox/api/v3/login/Login.php create mode 100644 freebox/utils/Application.php create mode 100644 freebox/utils/RestAuth.php diff --git a/freebox/api/v3/Service.php b/freebox/api/v3/Service.php new file mode 100644 index 0000000..31fbac7 --- /dev/null +++ b/freebox/api/v3/Service.php @@ -0,0 +1,41 @@ +application = $application; + } + + /** + * @param $service + * @return \alphayax\utils\Rest + */ + protected function getService( $service){ + return new \alphayax\utils\Rest( static::API_HOST . $service); + } + + /** + * @param $service + * @return \alphayax\freebox\utils\RestAuth + */ + protected function getAuthService( $service){ + $rest = new \alphayax\freebox\utils\RestAuth( static::API_HOST . $service); + $rest->setSessionToken( $this->application->getSessionToken()); + return $rest; + } +} diff --git a/freebox/api/v3/dhcp/DHCP.php b/freebox/api/v3/dhcp/DHCP.php new file mode 100644 index 0000000..29ccf46 --- /dev/null +++ b/freebox/api/v3/dhcp/DHCP.php @@ -0,0 +1,48 @@ + + */ +class DHCP extends Service { + + const API_DHCP_CONFIG = '/api/v3/dhcp/config/'; + + /** + * @throws \Exception + */ + public function get_current_configuration(){ + $rest = $this->getAuthService( self::API_DHCP_CONFIG); + $rest->GET(); + + $response = $rest->getCurlResponse(); + if( ! $response->success){ + throw new \Exception( __FUNCTION__ . ' Fail'); + } + + return $response; + } + + /** + * @param array $new_config_x + * @return array + * @throws \Exception + */ + public function set_attribute_configuration( $new_config_x = []){ + $rest = $this->getAuthService( self::API_DHCP_CONFIG); + $rest->setSessionToken( $this->application->getSessionToken()); + $rest->PUT( $new_config_x); + + $response = $rest->getCurlResponse(); + if( ! $response->success){ + throw new \Exception( __FUNCTION__ . ' Fail'); + } + + return $response; + } + +} diff --git a/freebox/api/v3/login/Authorize.php b/freebox/api/v3/login/Authorize.php new file mode 100644 index 0000000..d3633eb --- /dev/null +++ b/freebox/api/v3/login/Authorize.php @@ -0,0 +1,125 @@ + + */ +class Authorize extends Service { + + /// APIs services + const API_LOGIN_AUTHORIZE = '/api/v3/login/authorize/'; + + /// Authorization status + const STATUS_UNKNOWN = 'unknown'; + const STATUS_GRANTED = 'granted'; + const STATUS_PENDING = 'pending'; + const STATUS_DENIED = 'denied'; + const STATUS_TIMEOUT = 'timeout'; + + /** @var string */ + private $app_token = ''; + + /** @var int */ + private $track_id = 0; + + /** @var string */ + private $status = self::STATUS_UNKNOWN; + + /** @var string */ + private $challenge = ''; + + /** + * Authorize constructor. + * @param Application $application + * @throws \Exception + */ + public function __construct( Application $application){ + parent::__construct( $application); + + $this->application->loadAppToken(); + + if( ! $this->application->haveAppToken()){ + $this->ask_authorization(); + while( $this->status == self::STATUS_PENDING){ + $this->get_authorization_status(); + if( $this->status == self::STATUS_GRANTED){ + $this->application->saveAppToken(); + break; + } + sleep( 10); + } + + /// For verbose + switch( $this->status){ + case self::STATUS_GRANTED : Cli::stdout('Access granted !', 0, true, Cli::COLOR_GREEN); break; + case self::STATUS_TIMEOUT : Cli::stdout('Access denied. You take to long to authorize app', 0, true, Cli::COLOR_RED); break; + case self::STATUS_DENIED : Cli::stdout('Access denied. Freebox denied app connexion', 0, true, Cli::COLOR_RED); break; + } + } + } + + + /** + * Contact the freebox and ask for App auth + * @throws \Exception + */ + public function ask_authorization(){ + $rest = $this->getService( self::API_LOGIN_AUTHORIZE); + $rest->POST([ + 'app_id' => $this->application->getId(), + 'app_name' => $this->application->getName(), + 'app_version' => $this->application->getVersion(), + 'device_name' => gethostname(), + ]); + + $response = $rest->getCurlResponse(); + if( ! $response->success) { + throw new \Exception('Authorize fail. Unable to contact the freebox'); + } + + Cli::stdout( 'Authorization send to Freebox. Waiting for response...', 0, true, Cli::COLOR_YELLOW); + + $this->app_token = $response->result->app_token; + $this->track_id = $response->result->track_id; + } + + /** + * @throws \Exception + */ + public function get_authorization_status(){ + Cli::stdout( 'Check authorization status... ', 0, false, Cli::COLOR_YELLOW); + + $rest = $this->getService( self::API_LOGIN_AUTHORIZE . $this->track_id); + $rest->GET(); + + $response = $rest->getCurlResponse(); + if( ! $response->success) { + throw new \Exception(__FUNCTION__ . ' Fail'); + } + + $this->status = $response->result->status; + $this->challenge = $response->result->challenge; + + Cli::stdout( $this->status, 0, true, Cli::COLOR_BLUE); + } + + /** + * @return string + */ + public function getStatus(){ + return $this->status; + } + + /** + * @return string + */ + public function getAppToken(){ + return $this->app_token; + } + +} diff --git a/freebox/api/v3/login/Login.php b/freebox/api/v3/login/Login.php new file mode 100644 index 0000000..a6fd021 --- /dev/null +++ b/freebox/api/v3/login/Login.php @@ -0,0 +1,70 @@ + + */ +class Login extends Service { + + /// APIs services + const API_LOGIN = '/api/v3/login/'; + const API_LOGIN_SESSION = '/api/v3/login/session/'; + + /** @var string */ + private $challenge = ''; + + private $password_salt = ''; + + private $logged_in = false; + + + private $session_token; + + /** + * @throws \Exception + */ + public function ask_login_status(){ + $rest = $this->getService( static::API_LOGIN); + $rest->GET(); + + $response = $rest->getCurlResponse(); + if( ! $response->success){ + throw new \Exception( __FUNCTION__ . ' Fail'); + } + + $this->logged_in = $response->result->logged_in; + $this->challenge = $response->result->challenge; + $this->password_salt = $response->result->password_salt; + } + + /** + * @throws \Exception + */ + public function create_session(){ + $rest = $this->getService( static::API_LOGIN_SESSION); + $rest->POST([ + 'app_id' => DNS_changer::APP_ID, + 'password' => hash_hmac( 'sha1', $this->challenge, $this->application->getAppToken()), + ]); + + $response = $rest->getCurlResponse(); + if( ! $response->success){ + throw new \Exception( @$response->msg . ' '. @$response->error_code); + } + + $this->session_token = $response->result->session_token; + } + + /** + * @return mixed + */ + public function getSessionToken(){ + return $this->session_token; + } + +} diff --git a/freebox/utils/Application.php b/freebox/utils/Application.php new file mode 100644 index 0000000..49ae521 --- /dev/null +++ b/freebox/utils/Application.php @@ -0,0 +1,122 @@ +id = $app_id; + $this->name = $app_name; + $this->version = $app_version; + } + + /** + * Ask authorization to the freebox and save the app token + */ + public function authorize(){ + new api\v3\login\Authorize( $this); + } + + /** + * Open a new session and save the session token + * @throws \Exception + */ + public function openSession(){ + $Login = new api\v3\login\Login( $this); + $Login->ask_login_status(); + $Login->create_session(); + + $this->session_token = $Login->getSessionToken(); + } + + /** + * @return string + */ + public function getId(){ + return $this->id; + } + + /** + * @return string + */ + public function getName(){ + return $this->name; + } + + /** + * @return string + */ + public function getVersion(){ + return $this->version; + } + + /** + * @return string + */ + public function getSessionToken(){ + return $this->session_token; + } + + /** + * @return string + */ + public function getAppToken(){ + return $this->app_token; + } + + /** + * @param string $app_token + */ + public function setAppToken( $app_token){ + $this->app_token = $app_token; + } + + /** + * Indicate if a token is defined + */ + public function haveAppToken(){ + return ! empty( $this->app_token); + } + + /** + * @return string + */ + public function loadAppToken(){ + if( file_exists( 'app_token')){ + $this->app_token = file_get_contents( 'app_token'); + } + } + + /** + * Write the app token in a file for later use + */ + public function saveAppToken(){ + file_put_contents( 'app_token', $this->app_token); + } + +} diff --git a/freebox/utils/RestAuth.php b/freebox/utils/RestAuth.php new file mode 100644 index 0000000..8626d3c --- /dev/null +++ b/freebox/utils/RestAuth.php @@ -0,0 +1,54 @@ + + */ +class RestAuth extends \alphayax\utils\Rest { + + /** @var string */ + protected $session_token = ''; + + /** + * + */ + public function GET(){ + $this->add_XFbxAppAuth_Header(); + parent::GET(); + } + + /** + * @param $curl_post_data + */ + public function POST( $curl_post_data){ + $this->add_XFbxAppAuth_Header(); + parent::POST( $curl_post_data); + } + + /** + * @param $curl_post_data + */ + public function PUT( $curl_post_data){ + $this->add_XFbxAppAuth_Header(); + parent::PUT( $curl_post_data); + } + + /** + * Add the session token in the X-Fbx-App-Auth Header + */ + protected function add_XFbxAppAuth_Header(){ + curl_setopt( $this->_curl_handler, CURLOPT_HTTPHEADER, array( + 'X-Fbx-App-Auth: '. $this->session_token, + )); + } + + /** + * @param $session_token + */ + public function setSessionToken($session_token){ + $this->session_token = $session_token; + } +}