-- ****************************************************************************************************
-- *      ______                                                  _                       _           *
-- *     |  ____|                                           /\   (_)                     | |          *
-- *     | |__  _   _ _ __ ___  _ __   ___  __ _ _ __      /  \   _ _ __ _ __   ___  _ __| |_ ___     *
-- *     |  __|| | | | '__/ _ \| '_ \ / _ \/ _` | '_ \    / /\ \ | | '__| '_ \ / _ \| '__| __/ __|    *
-- *     | |___| |_| | | | (_) | |_) |  __/ (_| | | | |  / ____ \| | |  | |_) | (_) | |  | |_\__ \    *
-- *     |______\__,_|_|  \___/| .__/ \___|\__,_|_| |_| /_/    \_\_|_|  | .__/ \___/|_|   \__|___/    *
-- *                           | |                                      | |                           *
-- *                           |_|                                      |_|                           *
-- *                                                                                                  *
-- ****************************************************************************************************

-- This file is part of the European Airports Project, a free, collaborative platform of airport data 
-- extending beyond the official AIPs.

-- Copyright (C) 2023

-- Florian Meissner <florianmeissner@gmx.de>

-- This program is free software: you can redistribute it and/or modify it under the 
-- terms of the GNU General Public License as published by the Free Software Foundation, either 
-- version 3 of the License, or (at your option) any later version. This program is distributed in the 
-- hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 
-- details. You should have received a copy of the GNU General Public License along with this program. 
-- (license.md in the root folder of this project) If not, see <http://www.gnu.org/licenses/>.


USE mysql;

-- Create a user and grant rights from Docker secrets

-- The procedure expects the secrets base name. It will be expected that for each user the following 
-- secrets are mounted:
-- - BASENAME_name          The users username
-- - BASENAME_pw            The users password
-- - BASENAME_grantTable    The database table on which privileges should be granted. If missing or 
--                          empty, the privileges will be grated to *.*
-- - BASENAME_privileges    The privileges that should be granted on the above table. If missing or 
--                          empty, ALL PRIVILEGES will be granted.
DELIMITER $
CREATE OR REPLACE PROCEDURE `CREATE_USER`(
    IN `secretBase` VARCHAR(128)
) 
COMMENT 'Create a user from Docker secrets' 
CONTAINS SQL
BEGIN
    
    -- Read data from secrets
    SET @SECRET_PATH = '/run/secrets/';
    SET @username = LOAD_FILE(CONCAT(@SECRET_PATH, secretBase, "User"));
    SET @password = LOAD_FILE(CONCAT(@SECRET_PATH, secretBase, "Pw"));
    SET @grantTable = LOAD_FILE(CONCAT(@SECRET_PATH, secretBase, "GrantTable"));
    SET @privileges = LOAD_FILE(CONCAT(@SECRET_PATH, secretBase, "Privs"));
    
    -- Set defaults for missing or empty secrets
    SELECT 
        IF(
            ISNULL(@grantTable) OR @grantTable = "", 
            "*.*", 
            CONCAT("`", @grantTable, "`.*")
        ) 
        INTO @grantTable;
        
    SELECT 
        IF(
            ISNULL(@privileges) OR @privileges = "", 
            "ALL PRIVILEGES", 
            @privileges
        ) 
        INTO @privileges;
    
    -- Create user
    SET @query = CONCAT(
        "CREATE OR REPLACE USER `",@username,"` IDENTIFIED BY '",@password,"';"
    );
    PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt;

    -- Grant privileges
    SET @query = CONCAT(
        "GRANT ", @privileges, " ON ", @grantTable, " TO `", @username, "`@`%`;"
    );
    PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt;
        
    FLUSH PRIVILEGES;
END
$
DELIMITER ;

START TRANSACTION;

-- Call procedure
CALL CREATE_USER('root');
CALL CREATE_USER('eaBackend');
CALL CREATE_USER('checkmk');

COMMIT;