Implement API websocket auth
This commit is contained in:
parent
f7b274ec71
commit
3c64d67b4f
2 changed files with 38 additions and 11 deletions
|
@ -189,7 +189,7 @@ public:
|
||||||
std::string tags;
|
std::string tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Controller::handleWebSocket(HTTP::Parser &H, Socket::Connection &C){
|
void Controller::handleWebSocket(HTTP::Parser &H, Socket::Connection &C, bool authorized){
|
||||||
std::string logs = H.GetVar("logs");
|
std::string logs = H.GetVar("logs");
|
||||||
std::string accs = H.GetVar("accs");
|
std::string accs = H.GetVar("accs");
|
||||||
bool doStreams = H.GetVar("streams").size();
|
bool doStreams = H.GetVar("streams").size();
|
||||||
|
@ -198,6 +198,41 @@ void Controller::handleWebSocket(HTTP::Parser &H, Socket::Connection &C){
|
||||||
HTTP::Websocket W(C, req, H);
|
HTTP::Websocket W(C, req, H);
|
||||||
if (!W){return;}
|
if (!W){return;}
|
||||||
|
|
||||||
|
if (authorized){
|
||||||
|
W.sendFrame("[\"auth\", true]");
|
||||||
|
}else{
|
||||||
|
W.sendFrame("[\"auth\", false]");
|
||||||
|
C.setBlocking(false);
|
||||||
|
}
|
||||||
|
uint64_t authTime = Util::bootMS();
|
||||||
|
while (!authorized && W){
|
||||||
|
if (W.readFrame()){
|
||||||
|
|
||||||
|
//only handle text frames
|
||||||
|
if (W.frameType != 1){continue;}
|
||||||
|
|
||||||
|
//Parse JSON and check command type
|
||||||
|
JSON::Value command = JSON::fromString(W.data, W.data.size());
|
||||||
|
if (command.isArray() && command[0u].asString() == "auth"){
|
||||||
|
tthread::lock_guard<tthread::mutex> guard(configMutex);
|
||||||
|
JSON::Value req;
|
||||||
|
req["authorize"] = command[1u];
|
||||||
|
authorized = authorize(req, req, C);
|
||||||
|
W.sendFrame("[\"auth\", "+req["authorize"].toString()+"]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Util::sleep(100);
|
||||||
|
if (Util::bootMS() > authTime + 10000){
|
||||||
|
W.sendFrame("[\"auth\",\"Too slow, sorry\"]");
|
||||||
|
C.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!authorized || !W || !C){return;}
|
||||||
|
C.setBlocking(true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IPC::sharedPage shmLogs(SHM_STATE_LOGS, 1024 * 1024);
|
IPC::sharedPage shmLogs(SHM_STATE_LOGS, 1024 * 1024);
|
||||||
IPC::sharedPage shmAccs(SHM_STATE_ACCS, 1024 * 1024);
|
IPC::sharedPage shmAccs(SHM_STATE_ACCS, 1024 * 1024);
|
||||||
IPC::sharedPage shmStreams(SHM_STATE_STREAMS, 1024 * 1024);
|
IPC::sharedPage shmStreams(SHM_STATE_STREAMS, 1024 * 1024);
|
||||||
|
@ -364,15 +399,7 @@ int Controller::handleAPIConnection(Socket::Connection &conn){
|
||||||
}
|
}
|
||||||
// Catch websocket requests
|
// Catch websocket requests
|
||||||
if (H.url == "/ws"){
|
if (H.url == "/ws"){
|
||||||
if (!authorized){
|
handleWebSocket(H, conn, authorized);
|
||||||
H.Clean();
|
|
||||||
H.body = "Please login first or provide a valid token authentication.";
|
|
||||||
H.SetHeader("Server", APPIDENT);
|
|
||||||
H.SendResponse("403", "Not authorized", conn);
|
|
||||||
H.Clean();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
handleWebSocket(H, conn);
|
|
||||||
H.Clean();
|
H.Clean();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,6 @@ namespace Controller{
|
||||||
bool authorize(JSON::Value &Request, JSON::Value &Response, Socket::Connection &conn);
|
bool authorize(JSON::Value &Request, JSON::Value &Response, Socket::Connection &conn);
|
||||||
int handleAPIConnection(Socket::Connection &conn);
|
int handleAPIConnection(Socket::Connection &conn);
|
||||||
void handleAPICommands(JSON::Value &Request, JSON::Value &Response);
|
void handleAPICommands(JSON::Value &Request, JSON::Value &Response);
|
||||||
void handleWebSocket(HTTP::Parser &H, Socket::Connection &C);
|
void handleWebSocket(HTTP::Parser &H, Socket::Connection &C, bool authorized);
|
||||||
void handleUDPAPI(void *np);
|
void handleUDPAPI(void *np);
|
||||||
}// namespace Controller
|
}// namespace Controller
|
||||||
|
|
Loading…
Add table
Reference in a new issue