Lae/app/Http/Controllers/Application/MqttAuthController.php
2022-12-28 00:25:22 +08:00

156 lines
4.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Application;
use App\Http\Controllers\Controller;
use App\Models\Module;
use App\Models\ModuleAllow;
use Illuminate\Http\Request;
class MqttAuthController extends Controller
{
//
public function authentication(Request $request)
{
//
$client_id = $request->input('client_id');
$username = $request->input('username');
$password = $request->input('password');
// 分割 username
$usernames = explode('.', $username);
$module_id = $usernames[0] ?? null;
$device_id = $usernames[1] ?? null;
$module = Module::where('id', $module_id)->first();
if (!$module) {
return $this->ignore();
}
// 如果没有设置 device_id那么就是模块自己的连接
if (!$device_id) {
// 让 api_token 可见
$module->makeVisible('api_token');
// 比较 api_token
if ($module->api_token == $password) {
return $this->allow();
} else {
return $this->deny();
}
} else {
// 如果设置了 device_id那么就是设备的连接
// 此时,我们得联系模块,让模块去验证设备。
$response = $module->baseRequest('post', 'mqtt/authentication', [
'client_id' => $client_id,
'device_id' => $device_id,
'password' => $password,
]);
if ($response['status'] === 200) {
return $this->allow();
} else {
return $this->deny();
}
}
}
private function ignore()
{
return response([
'result' => 'ignore',
], 200);
}
private function allow()
{
return response([
'result' => 'allow',
'is_superuser' => false,
], 200);
}
private function deny()
{
return response([
'result' => 'deny',
], 200);
}
public function authorization(Request $request)
{
// 禁止订阅保留的
if ($request->input('topic') == '$SYS/#') {
return $this->deny();
}
$action = $request->input('action');
$client_id = $request->input('client_id');
$username = $request->input('username');
$topic = $request->input('topic');
if ($topic === '#') {
return $this->deny();
}
// 使用 / 分割 topic
$topics = explode('/', $topic);
$usernames = explode('.', $username);
$module_id = $usernames[0] ?? null;
$device_id = $usernames[1] ?? null;
$module = Module::where('id', $module_id)->first();
if (!$module) {
// 不属于我们管理,跳过。
// Log::debug('不属于我们管理,跳过。');
return $this->ignore();
}
// 设备只能在自己的模块下发布消息
if ($action == 'publish') {
if ($topics[0] !== $module_id) {
// 但是,在拒绝之前,应该检查一下,是否有允许的模块
$allow = ModuleAllow::where('module_id', $topics[0])->where('allowed_module_id', $module_id)->exists();
if (!$allow) {
return $this->deny();
}
}
}
if (count($usernames) === 1) {
// 是模块自己的连接
return $this->allow();
}
// 其他情况,让模块去验证
// 联系模块,让模块去验证设备授权。
$response = $module->baseRequest('post', 'mqtt/authorization', [
'client_id' => $client_id,
'device_id' => $device_id,
'type' => $action,
'topic' => $topic,
]);
if ($response['status'] === 200) {
return $this->allow();
} else {
return $this->deny();
}
}
}