Controle de acesso - workflow básico
Quando o service access_engine do Accelero recebe uma mensagem do tipo acc_req de algum controlador, é iniciado um processo de "consulta online": alguém está solicitando acesso em um bloqueio, e o servidor deve analisar a solicitação pra ver se "libera ou não libera".
O processo é detalhado a seguir.
Quando chega uma mensagem MQTT vinda do controlador, essa classe faz o roteamento (método routeCommand). Sendo uma mensagem do tipo acc_req, o processo se inicia.
Identificação do cartão/objeto
O número do cartão está presente na chave card.
Carrega o objeto Cartao do DB (campo carNumero) e vê que tipo de objeto está associado ao cartão.
- se for um
Veiculo, inicia tratamento de veículos. - se for qualquer outra coisa (
Pessoa, ou "nada"), inicia tratamento padrão.
Tratamento de veículo
Primeiro, checa-se a "consistência" dos dados:
- o controlador de onde a mensagem chegou realmente existe?
- o canal realmente está cadastrado?
- realmente conseguimos carregar um objeto
Veiculoassociado aoCartao?
Qualquer coisa que falhar, retornamos ACCESS_NOT_AUTHORIZED.
Em seguida, verificamos se o Cartao tem o flag de "coação" ativo (carCoercao). Se sim, "anota" que é uma coação e emite um evento EventHandler do tipo access_engine_duress.
É feita a checagem de acesso.
Envia mensagem MQTT para o controlador com a resposta definida na checagem de acesso.
Gera um LogEvento com todas as informações coletadas no processo.
Tratamento de não-veículos
Primeiro passo é determinar o tipo específico de tratamento necessário.
Se for possível, pelo número do cartão, determinar que trata-se um visitante-usando-QRCode (cartão cujo número se inicia com @v), usamos o tratador de eventos.
Se for possível, pelo tipo de cartão recebido do controlador (tp=CartaoInterface::CARTAO_QRDYN) determinar que trata-se de um QRCode dinâmico, usamos o tratador de QRCode dinâmico.
Do contrário, caímos no tratador padrão de acesso.
Tratamento de eventos
Primeiro, checa-se a "consistência" dos dados:
- o controlador de onde a mensagem chegou realmente existe?
- o canal realmente está cadastrado?
- foi possível realmente carregar um
Evento/LinkEventoPessoaa partir das informações recebidas? - a visita recuperada do DB está associada a algum app externo? Se sim, talvez exista algum ajuste a ser feito no número do cartão por <motivos>.
Qualquer coisa que falhar, retornamos ACCESS_NOT_AUTHORIZED.
Se o evento já estiver finalizado (visitante já saiu e está tentando voltar, por exemplo), checamos se isso é permitido de acordo com as configurações que foram feitas no sistema. Se não for permitido, ACCESS_NOT_AUTHORIZED.
É feita a checagem de acesso.
Se o Evento ainda não havia sido iniciado:
- atualiza o status do
LinkEventoPessoaespecífico paralepStatus=LinkEventoPessoaInterface::STATUS_STARTED - atualiza o status do evento para
evsID=EventoStatus::EVENTO_INICIADO - envia uma mensagem MQTT no tópico
<FACILITY>/evento-notification/startpara tratamento assíncrono.
Envia mensagem MQTT para o controlador com a resposta definida na checagem de acesso.
Gera um LogEvento com todas as informações coletadas no processo.
Tratamento de QRCodes dinâmicos
Primeiro, checa-se a "consistência" dos dados:
- o controlador de onde a mensagem chegou realmente existe?
- o canal realmente está cadastrado?
- foi possível extrair o
pesIDda pessoa do QRCode? - a pessoa existe?
- o timestamp do QRCode dinâmico é válido?
Qualquer coisa que falhar, retornamos ACCESS_NOT_AUTHORIZED.
Cria-se um Cartao "fake, mas válido" pra pessoa que foi identificada.
Faz-se uma verificação padrão de acesso a partir desse ponto.
Tratamento padrão de acesso
Primeiro, checa-se a "consistência" dos dados:
- o controlador de onde a mensagem chegou realmente existe?
- o canal realmente está cadastrado?
- o controlador mandou o número do cartão (
searchBy=ref) ou o ID da pessoa (searchBy=uid)? Foi possível achar uma pessoa usando essa informação? - se não foi possível achar uma pessoa, cria um objeto
Pessoafake só pra seguir o processo. - se a busca foi por UID, cria um objeto
Cartaofake, habilitado, só pra seguir o processo.
Qualquer coisa que falhar, retornamos ACCESS_NOT_AUTHORIZED.
Aproveitamos pra ver se a pessoa não tem "visita agendada e válida pra agora". Se sim, guardamos esse Evento.
Em seguida, verificamos se o Cartao tem o flag de "coação" ativo.
- se sim, "anota" que é uma coação e emite um evento
EventHandlerdo tipoaccess_engine_duress. - se sim e se o sistema estiver configurado pra "autorizar acesso em coação automaticamente", pula toda a checagem de acesso abaixo e vai direto para "enviar mensagem MQTT com o retorno".
Se conseguimos identificar que a pessoa tem, sim, uma "visita agendada e válida pra agora", então redireciona a checagem para o tratamento de eventos.
Se não havia nenhuma visita, é feita a checagem de acesso.
Envia mensagem MQTT para o controlador com a resposta definida na checagem de acesso.
Gera um LogEvento com todas as informações coletadas no processo.
Checagem de acesso
- se for um acesso bidirecional e se o sistema estiver configurado para "descobrir automaticamente a área atual do objeto" (autoDiscoverLocation), então tenta "desfazer a bidirecionalidade".
- se o canal estiver configurado para ser "canal de checkin" e se foi identificado que há um
Eventoenvolvido no acesso (o que, para veículos, sempre será falso), força o objetoCartaopara "habilitado". - em seguida, aplicam-se as regras de controle de acesso uma a uma.
- se qualquer regra falhar, nem se checam as próximas regras.
- se todas as regras "passarem", considera-se que o acesso está autorizado.
Se o acesso foi autorizado, marca o horário da autorização para poder controlar situações de "cartão em uso".
Se o acesso for de um Veiculo, anota-se o nome das pessoas/condutores atuais do Veiculo (linkpessoasveiculos) para incluir nos logs mais à frente.
Em seguida, selecionamos qual resposta realmente devemos enviar pro controlador:
- se o acesso foi bidirecional com "respostas diferentes pros dois lados", seleciona a "resposta mais restritiva".
- se o acesso foi unidirecional ou "bidirecional com a mesma resposta pros dois lados", então usaremos o código que foi determinado pela checagem.
Prepara-se no método generateResponseContextData a resposta para o controlador incluindo quaisquer informações adicionais que sejam necessárias (id da Pessoa/Veiculo que foi identificada... mensagem a ser apresentada no display... informações de retardo de abertura... hash de senha para verificação... instruções específicas para acesso bidirecional...).