267 lines
6.5 KiB
PHP
267 lines
6.5 KiB
PHP
<?php
|
|
|
|
require_once "Util.php";
|
|
|
|
class Service
|
|
{
|
|
public $type;
|
|
public $privileges;
|
|
|
|
public function __construct($serviceType)
|
|
{
|
|
$this->type = $serviceType;
|
|
}
|
|
|
|
public function addPrivilege($privilege, $expire)
|
|
{
|
|
$this->privileges[$privilege] = $expire;
|
|
}
|
|
|
|
public function getServiceType()
|
|
{
|
|
return $this->type;
|
|
}
|
|
|
|
public function pack()
|
|
{
|
|
return Util::packUint16($this->type) . Util::packMapUint32($this->privileges);
|
|
}
|
|
|
|
public function unpack(&$data)
|
|
{
|
|
$this->privileges = Util::unpackMapUint32($data);
|
|
}
|
|
}
|
|
|
|
class ServiceRtc extends Service
|
|
{
|
|
const SERVICE_TYPE = 1;
|
|
const PRIVILEGE_JOIN_CHANNEL = 1;
|
|
const PRIVILEGE_PUBLISH_AUDIO_STREAM = 2;
|
|
const PRIVILEGE_PUBLISH_VIDEO_STREAM = 3;
|
|
const PRIVILEGE_PUBLISH_DATA_STREAM = 4;
|
|
public $channelName;
|
|
public $uid;
|
|
|
|
public function __construct($channelName = "", $uid = "")
|
|
{
|
|
parent::__construct(self::SERVICE_TYPE);
|
|
$this->channelName = $channelName;
|
|
$this->uid = $uid;
|
|
}
|
|
|
|
public function pack()
|
|
{
|
|
return parent::pack() . Util::packString($this->channelName) . Util::packString($this->uid);
|
|
}
|
|
|
|
public function unpack(&$data)
|
|
{
|
|
parent::unpack($data);
|
|
$this->channelName = Util::unpackString($data);
|
|
$this->uid = Util::unpackString($data);
|
|
}
|
|
}
|
|
|
|
class ServiceRtm extends Service
|
|
{
|
|
const SERVICE_TYPE = 2;
|
|
const PRIVILEGE_LOGIN = 1;
|
|
public $userId;
|
|
|
|
public function __construct($userId = "")
|
|
{
|
|
parent::__construct(self::SERVICE_TYPE);
|
|
$this->userId = $userId;
|
|
}
|
|
|
|
public function pack()
|
|
{
|
|
return parent::pack() . Util::packString($this->userId);
|
|
}
|
|
|
|
public function unpack(&$data)
|
|
{
|
|
parent::unpack($data);
|
|
$this->userId = Util::unpackString($data);
|
|
}
|
|
}
|
|
|
|
class ServiceFpa extends Service
|
|
{
|
|
const SERVICE_TYPE = 4;
|
|
const PRIVILEGE_LOGIN = 1;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct(self::SERVICE_TYPE);
|
|
}
|
|
|
|
public function pack()
|
|
{
|
|
return parent::pack();
|
|
}
|
|
|
|
public function unpack(&$data)
|
|
{
|
|
parent::unpack($data);
|
|
}
|
|
}
|
|
|
|
class ServiceChat extends Service
|
|
{
|
|
const SERVICE_TYPE = 5;
|
|
const PRIVILEGE_USER = 1;
|
|
const PRIVILEGE_APP = 2;
|
|
public $userId;
|
|
|
|
public function __construct($userId = "")
|
|
{
|
|
parent::__construct(self::SERVICE_TYPE);
|
|
$this->userId = $userId;
|
|
}
|
|
|
|
public function pack()
|
|
{
|
|
return parent::pack() . Util::packString($this->userId);
|
|
}
|
|
|
|
public function unpack(&$data)
|
|
{
|
|
parent::unpack($data);
|
|
$this->userId = Util::unpackString($data);
|
|
}
|
|
}
|
|
|
|
class ServiceApaas extends Service
|
|
{
|
|
const SERVICE_TYPE = 7;
|
|
const PRIVILEGE_ROOM_USER = 1;
|
|
const PRIVILEGE_USER = 2;
|
|
const PRIVILEGE_APP = 3;
|
|
|
|
public $roomUuid;
|
|
public $userUuid;
|
|
public $role;
|
|
|
|
|
|
public function __construct($roomUuid = "", $userUuid = "", $role = -1)
|
|
{
|
|
parent::__construct(self::SERVICE_TYPE);
|
|
$this->roomUuid = $roomUuid;
|
|
$this->userUuid = $userUuid;
|
|
$this->role = $role;
|
|
}
|
|
|
|
public function pack()
|
|
{
|
|
return parent::pack() . Util::packString($this->roomUuid) . Util::packString($this->userUuid) . Util::packInt16($this->role);
|
|
}
|
|
|
|
public function unpack(&$data)
|
|
{
|
|
parent::unpack($data);
|
|
$this->roomUuid = Util::unpackString($data);
|
|
$this->userUuid = Util::unpackString($data);
|
|
$this->role = Util::unpackInt16($data);
|
|
}
|
|
}
|
|
|
|
class AccessToken2
|
|
{
|
|
const VERSION = "007";
|
|
const VERSION_LENGTH = 3;
|
|
public $appCert;
|
|
public $appId;
|
|
public $expire;
|
|
public $issueTs;
|
|
public $salt;
|
|
public $services = [];
|
|
|
|
public function __construct($appId = "", $appCert = "", $expire = 900)
|
|
{
|
|
$this->appId = $appId;
|
|
$this->appCert = $appCert;
|
|
$this->expire = $expire;
|
|
$this->issueTs = time();
|
|
$this->salt = rand(1, 99999999);
|
|
}
|
|
|
|
public function addService($service)
|
|
{
|
|
$this->services[$service->getServiceType()] = $service;
|
|
}
|
|
|
|
public function build()
|
|
{
|
|
if (!self::isUUid($this->appId) || !self::isUUid($this->appCert)) {
|
|
return "";
|
|
}
|
|
|
|
$signing = $this->getSign();
|
|
$data = Util::packString($this->appId) . Util::packUint32($this->issueTs) . Util::packUint32($this->expire)
|
|
. Util::packUint32($this->salt) . Util::packUint16(count($this->services));
|
|
|
|
ksort($this->services);
|
|
foreach ($this->services as $key => $service) {
|
|
$data .= $service->pack();
|
|
}
|
|
|
|
$signature = hash_hmac("sha256", $data, $signing, true);
|
|
|
|
return self::getVersion() . base64_encode(zlib_encode(Util::packString($signature) . $data, ZLIB_ENCODING_DEFLATE));
|
|
}
|
|
|
|
public function getSign()
|
|
{
|
|
$hh = hash_hmac("sha256", $this->appCert, Util::packUint32($this->issueTs), true);
|
|
return hash_hmac("sha256", $hh, Util::packUint32($this->salt), true);
|
|
}
|
|
|
|
public static function getVersion()
|
|
{
|
|
return self::VERSION;
|
|
}
|
|
|
|
public static function isUUid($str)
|
|
{
|
|
if (strlen($str) != 32) {
|
|
return false;
|
|
}
|
|
return ctype_xdigit($str);
|
|
}
|
|
|
|
public function parse($token)
|
|
{
|
|
if (substr($token, 0, self::VERSION_LENGTH) != self::getVersion()) {
|
|
return false;
|
|
}
|
|
|
|
$data = zlib_decode(base64_decode(substr($token, self::VERSION_LENGTH)));
|
|
$signature = Util::unpackString($data);
|
|
$this->appId = Util::unpackString($data);
|
|
$this->issueTs = Util::unpackUint32($data);
|
|
$this->expire = Util::unpackUint32($data);
|
|
$this->salt = Util::unpackUint32($data);
|
|
$serviceNum = Util::unpackUint16($data);
|
|
|
|
$servicesObj = [
|
|
ServiceRtc::SERVICE_TYPE => new ServiceRtc(),
|
|
ServiceRtm::SERVICE_TYPE => new ServiceRtm(),
|
|
ServiceFpa::SERVICE_TYPE => new ServiceFpa(),
|
|
ServiceChat::SERVICE_TYPE => new ServiceChat(),
|
|
ServiceApaas::SERVICE_TYPE => new ServiceApaas(),
|
|
];
|
|
for ($i = 0; $i < $serviceNum; $i++) {
|
|
$serviceTye = Util::unpackUint16($data);
|
|
$service = $servicesObj[$serviceTye];
|
|
if ($service == null) {
|
|
return false;
|
|
}
|
|
$service->unpack($data);
|
|
$this->services[$serviceTye] = $service;
|
|
}
|
|
return true;
|
|
}
|
|
}
|