From 4c1102fc15513b9a4f656eadff4fe15126de3090 Mon Sep 17 00:00:00 2001 From: dakriy Date: Wed, 15 Apr 2020 02:19:19 -0700 Subject: [PATCH] It can authenticate a doorcode now! :D. OTA updates is next! --- docker-compose.yml.example | 10 +- src/embedded/CMakeLists.txt | 2 +- src/embedded/esp32.Dockerfile | 21 -- src/embedded/main/CMakeLists.txt | 14 +- src/embedded/main/api.c | 21 ++ src/embedded/main/api.h | 14 ++ src/embedded/main/config.h.example | 10 +- src/embedded/main/http.c | 180 ++++++++++++++++++ src/embedded/main/http.h | 35 ++++ src/embedded/main/main.c | 79 ++------ src/embedded/main/wifi.c | 134 ++++++++----- src/embedded/main/wifi.h | 11 +- .../DoorUser/LocalDoorUserRepository.php | 1 + 13 files changed, 380 insertions(+), 152 deletions(-) delete mode 100644 src/embedded/esp32.Dockerfile create mode 100644 src/embedded/main/api.c create mode 100644 src/embedded/main/api.h create mode 100644 src/embedded/main/http.c create mode 100644 src/embedded/main/http.h diff --git a/docker-compose.yml.example b/docker-compose.yml.example index 82a02a9d..a1206169 100644 --- a/docker-compose.yml.example +++ b/docker-compose.yml.example @@ -95,14 +95,10 @@ services: networks: - doorcode esp32: - build: - context: ./src/embedded - dockerfile: ./esp32.Dockerfile + image: espressif/idf:latest tty: true container_name: esp32 volumes: - ./src/embedded:/project - # This only works on linux - - /dev:/dev - ports: - - "2222:22" + devices: + - /dev/ttyUSB0:/dev/ttyUSB0 diff --git a/src/embedded/CMakeLists.txt b/src/embedded/CMakeLists.txt index f76dbc12..07873b30 100644 --- a/src/embedded/CMakeLists.txt +++ b/src/embedded/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(door) +project(door-controller) diff --git a/src/embedded/esp32.Dockerfile b/src/embedded/esp32.Dockerfile deleted file mode 100644 index f432a735..00000000 --- a/src/embedded/esp32.Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM espressif/idf:latest - -RUN apt-get update \ - && apt-get install -y ssh \ - rsync \ - tar \ - && apt-get clean \\ - && pip install --no-cache-dir -r /opt/esp/idf/requirements.txt - -RUN ( \ -echo 'LogLevel DEBUG2'; \ -echo 'PermitRootLogin yes'; \ -echo 'PasswordAuthentication yes'; \ -echo 'Subsystem sftp /usr/lib/openssh/sftp-server'; \ -) > /etc/ssh/sshd_config_container \ -&& mkdir /run/sshd - -RUN groupmod -g 985 users && useradd -u 1000 -ms /bin/bash -g users builder \ -&& yes password | passwd builder - -CMD ["/usr/sbin/sshd", "-D", "-e", "-f", "/etc/ssh/sshd_config_container"] diff --git a/src/embedded/main/CMakeLists.txt b/src/embedded/main/CMakeLists.txt index d5cad0fc..c2f3ebf0 100644 --- a/src/embedded/main/CMakeLists.txt +++ b/src/embedded/main/CMakeLists.txt @@ -1,11 +1,3 @@ -set(COMPONENT_SRCS "wifi.c" - "main.c") -set(COMPONENT_ADD_INCLUDEDIRS ".") - - -# Embed the server root certificate into the final binary -# -# (If this was a component, we would set COMPONENT_EMBED_TXTFILES here.) -set(COMPONENT_EMBED_TXTFILES doorcode_root_cert.pem) - -register_component() +idf_component_register(SRCS "wifi.c" "main.c" "http.c" "api.c" + INCLUDE_DIRS "." + EMBED_TXTFILES "doorcode_root_cert.pem") diff --git a/src/embedded/main/api.c b/src/embedded/main/api.c new file mode 100644 index 00000000..dd1d7015 --- /dev/null +++ b/src/embedded/main/api.c @@ -0,0 +1,21 @@ +#include +#include "api.h" +#include "http.h" +#include "config.h" + +#define ACCESS_PREFIX "/access/" +#define MAX_CODE_COUNT 500 + +bool door_api_verify_code(const char* code) +{ + // ignore null terminators, having 3 or so more bytes won't hurt anything +#define MAX_DOOR_CODE_PATH_SIZE (MAX_CODE_COUNT + sizeof(API_BASE_PATH) + sizeof(ACCESS_PREFIX) + sizeof(API_TOKEN)) + if (strlen(code) > MAX_CODE_COUNT) + return false; + char endpoint[MAX_DOOR_CODE_PATH_SIZE] = {0}; + strcat(endpoint, API_BASE_PATH ACCESS_PREFIX); + strcat(endpoint, code); + strcat(endpoint, "?" API_TOKEN); + return door_http_get(endpoint, NULL, NULL) == 200; +#undef MAX_DOOR_CODE_PATH_SIZE +} diff --git a/src/embedded/main/api.h b/src/embedded/main/api.h new file mode 100644 index 00000000..59a6fbb2 --- /dev/null +++ b/src/embedded/main/api.h @@ -0,0 +1,14 @@ +#ifndef DOOR_CONTROLLER_MAIN_API_H_ +#define DOOR_CONTROLLER_MAIN_API_H_ + +#include + +// Requires door_wifi to be initialized + +/** + * @param code MUST be null terminated + * @return + */ +bool door_api_verify_code(const char* code); + +#endif //DOOR_CONTROLLER_MAIN_API_H_ diff --git a/src/embedded/main/config.h.example b/src/embedded/main/config.h.example index 96fc3368..bd97ef73 100644 --- a/src/embedded/main/config.h.example +++ b/src/embedded/main/config.h.example @@ -3,7 +3,13 @@ #define DOOR_WIFI_SSID "ssid" #define DOOR_WIFI_PASSWORD "password" -#define API_TOKEN "api token" -#define API_BASE_URL "https://doorcode:port/api" + +#define API_TOKEN "api_token=door_1_api_token" +#define API_BASE_PATH "/api/door" +#define API_USE_SSL + +//#define API_NO_NAME_VERIFY +#define API_HOST "192.168.2.1" +#define API_PORT 8080 #endif //DOOR_CONFIG_H diff --git a/src/embedded/main/http.c b/src/embedded/main/http.c new file mode 100644 index 00000000..129b4f0d --- /dev/null +++ b/src/embedded/main/http.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include "http.h" +#include "config.h" +#include "wifi.h" + +/** + * @brief Input buffer + */ +static char* _buffer = NULL; + +/** + * @brief Input buffer size + */ +static int _buffer_bytes_written = 0; + +static const char* TAG = "DOOR HTTP MODULE"; + +static esp_http_client_handle_t _client = NULL; + +void door_http_free_buffer(void) +{ + free(_buffer); + _buffer = NULL; + _buffer_bytes_written = 0; +} + +/** + * This function assumes that only one request is placed at a time. + * This is fine currently as I am using blocking calls to get data, + * but if this is ever changed the way this function works will also + * need to be changed. + * + * @brief Event handler for the ESP http event handler + * @return + */ +static esp_err_t _http_event_handler(esp_http_client_event_t* evt) +{ + switch (evt->event_id) + { + case HTTP_EVENT_ERROR: + ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); + break; + case HTTP_EVENT_ON_CONNECTED: + ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); + break; + case HTTP_EVENT_HEADER_SENT: + ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); + break; + case HTTP_EVENT_ON_HEADER: + ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); + break; + case HTTP_EVENT_ON_DATA: + ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); + ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, data: %.*s", evt->data_len, (char*)evt->data); + // If user_data buffer is configured, copy the response into the buffer + if (!esp_http_client_is_chunked_response(evt->client)) { + if (evt->user_data) + { + memcpy(evt->user_data + _buffer_bytes_written, evt->data, evt->data_len); + } + else + { + if (!_buffer) + { + int content_length = esp_http_client_get_content_length(evt->client); + ESP_LOGI(TAG, "Allocating %d bytes for buffer", content_length); + _buffer = (char*)malloc(content_length); + _buffer_bytes_written = 0; + if (!_buffer && content_length != 0) + { + ESP_LOGE(TAG, "Failed to allocate memory for output buffer"); + return ESP_FAIL; + } + } + } + } else { + // create new buffer with adequate size. + char* new_buffer = (char*)malloc(_buffer_bytes_written + evt->data_len); + if (!new_buffer) { + ESP_LOGE(TAG, "Failed to allocate memory for output buffer"); + return ESP_FAIL; + } + memcpy(new_buffer, _buffer, _buffer_bytes_written); + free(_buffer); + _buffer = new_buffer; + } + memcpy(_buffer + _buffer_bytes_written, evt->data, evt->data_len); + _buffer_bytes_written += evt->data_len; + break; + case HTTP_EVENT_ON_FINISH: + ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); + break; + case HTTP_EVENT_DISCONNECTED: + ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED"); + int mbedtls_err = 0; + esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL); + if (err != 0) + { + if (_buffer != NULL) + door_http_free_buffer(); + ESP_LOGI(TAG, "Last esp error code: 0x%x", err); + ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err); + } + break; + default: + break; + } + + return ESP_OK; +} + +extern const char _door_root_cert_pem_start[] asm("_binary_doorcode_root_cert_pem_start"); + +static esp_http_client_config_t _http_base_config = { + .event_handler = _http_event_handler, + .host = API_HOST, + .port = API_PORT, + .path = API_BASE_PATH, +#ifdef API_USE_SSL + .transport_type = HTTP_TRANSPORT_OVER_SSL, +#ifdef API_NO_NAME_VERIFY + .skip_cert_common_name_check = false, +#endif +#else + .transport_type = HTTP_TRANSPORT_OVER_TCP, +#endif +}; + +int door_http_init(void) +{ + if (_client) + return DOOR_HTTP_ERR_SUCCESS; + + if (!door_wifi_is_connected()) { + ESP_LOGE(TAG, "Not connected to wifi."); + return DOOR_HTTP_ERR_FAIL; + } + + _http_base_config.cert_pem = _door_root_cert_pem_start; + _client = esp_http_client_init(&_http_base_config); + if (!_client) + { + ESP_LOGE(TAG, "Failed to initialize the esp http client"); + return DOOR_HTTP_ERR_FAIL; + } + return DOOR_HTTP_ERR_SUCCESS; +} + +void door_http_destroy(void) +{ + door_http_free_buffer(); + esp_http_client_cleanup(_client); + _client = NULL; +} + +int door_http_get(const char* path, char** buffer, int* buffer_len) +{ + ESP_LOGI(TAG, "DOOR_HTTP_SET: sending GET request to: %s", path); + if (!door_wifi_is_connected() || !_client) { + ESP_LOGI(TAG, "Not connected to wifi or client in call to get"); + return DOOR_HTTP_ERR_FAIL; + } + + esp_http_client_set_url(_client, path); + esp_http_client_set_method(_client, HTTP_METHOD_GET); + esp_http_client_perform(_client); + + if (buffer) + *buffer = _buffer; + if (buffer_len) + *buffer_len = _buffer_bytes_written; + + ESP_LOGI(TAG, "Total data retrieved from response: %.*s", _buffer_bytes_written, _buffer); + + int status_code = esp_http_client_get_status_code(_client); + ESP_LOGI(TAG, "Status code from get call: %d", status_code); + return status_code; +} diff --git a/src/embedded/main/http.h b/src/embedded/main/http.h new file mode 100644 index 00000000..024d3131 --- /dev/null +++ b/src/embedded/main/http.h @@ -0,0 +1,35 @@ +#ifndef DOOR_CONTROLLER_MAIN_HTTP_H_ +#define DOOR_CONTROLLER_MAIN_HTTP_H_ + +#define DOOR_HTTP_ERR_SUCCESS 0 +#define DOOR_HTTP_ERR_FAIL 1 + +/** + * @brief Frees the buffer for the next request. Must be called after every request + */ +void door_http_free_buffer(void); + +/** + * @brief Initializes the door http system + * @return < 0 on failure + */ +int door_http_init(void); + +/** + * @brief De-initalizes the http system. If it is to be used again, door_http_init must be called again + */ +void door_http_destroy(void); + +/** + * @brief Performs a get request to the door code server. door_http_free_buffer must be called + * when the callee is done with the data before the next request + * @param[in] path the path of the url to make the request to + * @param[out] buffer the buffer data + * @param[out] buffer_len the number of bytes written + * @return + * - status code on success + * - < 0 on fail + */ +int door_http_get(const char* path, char** buffer, int* buffer_len); + +#endif //DOOR_CONTROLLER_MAIN_HTTP_H_ diff --git a/src/embedded/main/main.c b/src/embedded/main/main.c index aff80d25..a5969d17 100644 --- a/src/embedded/main/main.c +++ b/src/embedded/main/main.c @@ -7,82 +7,35 @@ CONDITIONS OF ANY KIND, either express or implied. */ #include -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "config.h" +#include +#include +#include +#include #include "wifi.h" +#include "http.h" +#include "api.h" -static const char* TAG = "HTTPS_MODULE"; +static const char* TAG = "MAIN_MODULE"; -extern const char doorcode_root_cert_pem_start[] asm("_binary_doorcode_root_cert_pem_start"); -//extern const char doorcode_root_cert_pem_end[] asm("_binary_doorcode_root_cert_pem_end"); - -esp_err_t _http_event_handler(esp_http_client_event_t* evt) -{ - switch (evt->event_id) - { - case HTTP_EVENT_ERROR: - ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); - break; - case HTTP_EVENT_ON_CONNECTED: - ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); - break; - case HTTP_EVENT_HEADER_SENT: - ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); - break; - case HTTP_EVENT_ON_HEADER: - ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); - break; - case HTTP_EVENT_ON_DATA: - ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); - ESP_LOGI(TAG, "%.*s", evt->data_len, (char*)evt->data); - break; - case HTTP_EVENT_ON_FINISH: - ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); - break; - case HTTP_EVENT_DISCONNECTED: - ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED"); - break; - } - return ESP_OK; -} - -static void http_task(void* pvParameters) +static void check_code_task(void* pvParameters) { (void)pvParameters; door_wifi_wait_connected(); + door_http_init(); ESP_LOGI(TAG, "Connected to AP, begin connecting to DoorCode API"); - esp_http_client_config_t config = { - .url = API_BASE_URL "/door?api_token=" API_TOKEN, - .event_handler = _http_event_handler, - .cert_pem = doorcode_root_cert_pem_start, - .skip_cert_common_name_check = true, - }; - - esp_http_client_handle_t client = esp_http_client_init(&config); - - esp_err_t err = esp_http_client_perform(client); - - if (err == ESP_OK) + bool allowed = door_api_verify_code("123866"); + if (allowed) { - ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %d", - esp_http_client_get_status_code(client), - esp_http_client_get_content_length(client)); + ESP_LOGI(TAG, "We are allowed in the door!"); } else { - ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); + ESP_LOGI(TAG, "REJECTED"); } - esp_http_client_cleanup(client); + door_http_destroy(); + door_wifi_destroy(); ESP_LOGI(TAG, "Finished Request"); vTaskDelete(NULL); } @@ -100,5 +53,5 @@ void app_main() door_wifi_initialize(); - xTaskCreate(&http_task, "http_task", 8192, NULL, 5, NULL); + xTaskCreate(&check_code_task, "http_task", 8192, NULL, 5, NULL); } diff --git a/src/embedded/main/wifi.c b/src/embedded/main/wifi.c index fc290ae4..b6ddcfeb 100644 --- a/src/embedded/main/wifi.c +++ b/src/embedded/main/wifi.c @@ -1,65 +1,111 @@ -#include "wifi.h" +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" -#include "freertos/event_groups.h" -#include "config.h" +#include "nvs_flash.h" -static const char* TAG = "WIFI_MODULE"; - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; +#include "config.h" +#include "wifi.h" -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; +static const char* TAG = "wifi module"; +static const unsigned WIFI_CONNECTED_BIT = BIT0; +static esp_event_handler_instance_t instance_any_id; +static esp_event_handler_instance_t instance_got_ip; -static esp_err_t event_handler(void* ctx, system_event_t* event) +static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - (void)ctx; - switch (event->event_id) + (void)arg; + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - case SYSTEM_EVENT_STA_START: esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_STOP) + { + xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + ESP_LOGI(TAG, "WIFI Module is stopping..."); + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + ESP_LOGI(TAG, "Lost connection to the AP, retrying connection.."); esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - ESP_LOGI(TAG, "Lost connection to Wireless AP, Reconnecting...\n"); - break; - default: - break; } - return ESP_OK; + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data; + ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } } +bool door_wifi_is_connected(void) +{ + return xEventGroupGetBits(s_wifi_event_group) & WIFI_CONNECTED_BIT; +} + +void door_wifi_destroy(void) +{ + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_got_ip)); + vEventGroupDelete(s_wifi_event_group); +} void door_wifi_initialize(void) { - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)) - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT() - ESP_ERROR_CHECK(esp_wifi_init(&cfg)) - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)) + s_wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + esp_netif_create_default_wifi_sta(); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id)); + ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip)); + wifi_config_t wifi_config = { - .sta = { - .ssid = DOOR_WIFI_SSID, - .password = DOOR_WIFI_PASSWORD, - }, + .sta = { + .ssid = DOOR_WIFI_SSID, + .password = DOOR_WIFI_PASSWORD + }, }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)) - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)) - ESP_ERROR_CHECK(esp_wifi_start()) + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + ESP_LOGI(TAG, "WiFi initialization finished successfully."); } void door_wifi_wait_connected(void) { - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + EventBits_t bits; + do + { + bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + if (bits & WIFI_CONNECTED_BIT) + { + break; + } + } while (!(bits & WIFI_CONNECTED_BIT)); } diff --git a/src/embedded/main/wifi.h b/src/embedded/main/wifi.h index a107db51..a931fc5c 100644 --- a/src/embedded/main/wifi.h +++ b/src/embedded/main/wifi.h @@ -1,7 +1,12 @@ -#ifndef DOOR_WIFI_H -#define DOOR_WIFI_H +#ifndef DOOR__WIFI_H_ +#define DOOR__WIFI_H_ void door_wifi_initialize(void); + +void door_wifi_destroy(void); + +bool door_wifi_is_connected(void); + void door_wifi_wait_connected(void); -#endif //DOOR_WIFI_H +#endif //DOOR__WIFI_H_ diff --git a/src/web/backend/src/Gateways/DoorUser/LocalDoorUserRepository.php b/src/web/backend/src/Gateways/DoorUser/LocalDoorUserRepository.php index d954670d..b3c2f24b 100644 --- a/src/web/backend/src/Gateways/DoorUser/LocalDoorUserRepository.php +++ b/src/web/backend/src/Gateways/DoorUser/LocalDoorUserRepository.php @@ -17,6 +17,7 @@ class LocalDoorUserRepository extends InMemoryDoorUserRepository GroupUserRepository $groupUser, DoorGroupRepository $doorGroup ) { + // Automatically add all users to all doors, and all doors to all users foreach ($users->all() as $user) { try { foreach ($groupUser->getGroupsForUser($user->getId()) as $group) { -- GitLab