Index: /branches/rel_ag_9_4_5/lighttpd/saml2.diff
===================================================================
--- /branches/rel_ag_9_4_5/lighttpd/saml2.diff	(revision 20389)
+++ /branches/rel_ag_9_4_5/lighttpd/saml2.diff	(working copy)
@@ -2300,15 +2300,18 @@
 +}
 diff -urNa simplesamlphp-1.14.16/lib/AN/GroupAPI.php simplesamlphp/lib/AN/GroupAPI.php
 --- simplesamlphp-1.14.16/lib/AN/GroupAPI.php	1970-01-01 08:00:00.000000000 +0800
-+++ simplesamlphp/lib/AN/GroupAPI.php	2024-12-20 14:10:12.000000000 +0800
-@@ -0,0 +1,203 @@
++++ simplesamlphp/lib/AN/GroupAPI.php	2025-03-03 14:58:26.000000000 +0800
+@@ -0,0 +1,372 @@
 +<?php
 +
++include_once("/ca/webui/htdocs/proxy/new/cli_define.inc");
++
 +class GroupAPI
 +{
 +    const URL_OF_GET_TOKEN = "https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"; // Need to replace tenant_id
 +    const URL_OF_GROUP_ID = "https://graph.microsoft.com/v1.0/groups/"; // Need add group id to the end
 +    const CONFIG_FILE = "GraphAPIConfig.php";
++    const USERNAME_ARRAY = "array";
 +
 +    private static $access_token;
 +
@@ -2483,7 +2486,7 @@
 +    }
 +
 +    /**
-+     * Get parameter of Graph API from configuration file
++     * Get parameter of Graph API from cli
 +     * @return array: param of Graph API
 +     */
 +    public static function getParam()
@@ -2493,17 +2496,183 @@
 +            'client_id' => '',
 +            'client_secret' => '',
 +        );
-+        if (!file_exists(__DIR__ . "/" . self::CONFIG_FILE)) {
-+            return $config;
-+        }
-+        $get_config = file_get_contents(__DIR__ . "/" . self::CONFIG_FILE);
-+        if ($get_config !== false && !empty($get_config)) {
-+            $remove_new_line = str_replace("\n", "", $get_config);
-+            $config = json_decode($remove_new_line, true);
++        $setting = self::exec_direct(CMD_SHOW_AAA_SAML_MSGRAPHAPI);
++        if (!empty($setting->content) && !empty($setting->content[0])) {
++            if (!empty($setting->content[0]->tenant_id)) {
++                $config['tenant_id'] = $setting->content[0]->tenant_id;
++            }
++            if (!empty($setting->content[0]->client_id)) {
++                $config['client_id'] = $setting->content[0]->client_id;
++            }
++            if (!empty($setting->content[0]->client_secret)) {
++                $config['client_secret'] = $setting->content[0]->client_secret;
++            }
 +        }
 +        return $config;
 +    }
 +
++    /*************************************************************************
++     *
++     * SPXII: Execute a CLI command directly from backend
++     *
++     * @param string	CLI format string
++     * @param mixed         printf like variable arguments
++     *
++     *************************************************************************/
++    function exec_direct($cmd_format)
++    {
++        $numargs = func_num_args();
++        $arg_list = func_get_args();
++        array_shift($arg_list);
++        $cmd = vsprintf($cmd_format, $arg_list);
++
++        //------------------------------------------------------------------------
++        // CLI command line parameter tokens
++        //------------------------------------------------------------------------
++        $sp1 = explode("simplesamlphp-", __FILE__);
++        $sp1_cont = $sp1[1]; // ex: test/
++        $sp2 = explode("/", trim($sp1_cont));
++        $shell = $sp2[0]; // ex: test
++        $f_eop = chr(252); // end of username (webui_agent.c)
++        $cmd .= $f_eop;
++        $username = self::USERNAME_ARRAY;
++
++        $cmd = escapeshellarg($cmd);
++        $output = `/ca/bin/backend -s "$shell" -u "$username" -c $cmd`;
++        $output = trim($output, $f_eop);
++
++        $output = self::backend_format($output);
++        $json = json_decode($output);
++        if (!$json) {
++            return $output;
++        }
++        return $json;
++    }
++
++    function backend_format($output)
++    {
++        $history_ch_status = 0;
++        $ch = '';
++        $new = '';
++        $output = trim($output);//strip whitespace from the beginning and end of str
++        for ($i = 0; $i<strlen($output); $i++) {
++            $ch = $output[$i];
++                if ($history_ch_status == 0) {
++                switch ($ch) {
++                case "\\":
++                    $history_ch_status = 1;
++                    break;
++                case "\r":
++                    $new .= "\\r";
++                    break;
++                case "\n":
++                    $new .= "\\n";
++                    break;
++                case "\t":
++                    $new .= "\\t";
++                    break;
++                default:
++                    $new .= $ch;
++                    break;
++                }
++            } else if ($history_ch_status == 1) {
++                switch ($ch) {
++                case "\\":
++                    $new .= "\\\\\\\\";
++                    $history_ch_status = 0;
++                    break;
++                case "\r":
++                    $new .= "\\\\\\r";
++                    $history_ch_status = 0;
++                    break;
++                case "\n":
++                    $new .= "\\\\\\n";
++                    $history_ch_status = 0;
++                    break;
++                case "\t":
++                    $new .= "\\\\\\t";
++                    $history_ch_status = 0;
++                    break;
++                case "\"":
++                    $history_ch_status = 2;
++                    break;
++                default:
++                    $new .= "\\\\";
++                    $new .= $ch;
++                    $history_ch_status = 0;
++                    break;
++                }
++            } else if ($history_ch_status == 2) {
++                switch ($ch) {
++                case "\\":
++                    $new .= "\\\"";
++                    $history_ch_status = 1;
++                    break;
++                case "\r":
++                    $new .= "\\\"\\r";
++                    $history_ch_status = 0;
++                    break;
++                case "\n":
++                    $new .= "\\\"\\n";
++                    $history_ch_status = 0;
++                    break;
++                case "\t":
++                    $new .= "\\\"\\t";
++                    $history_ch_status = 0;
++                    break;
++                case ",":
++                    /* not yet sure whether it's a end of value */
++                    $history_ch_status = 3;
++                    break;
++                case "]":
++                case "}":
++                    /* meet end of a value, which means previous \" is end of the value */
++                    $new .= "\\\\\"";
++                    $new .= $ch;
++                    $history_ch_status = 0;
++                    break;
++                default:
++                    /* previous \" is inside a value */
++                    $new .= "\\\"";
++                    $new .= $ch;
++                    $history_ch_status = 0;
++                    break;
++                }
++            } else if ($history_ch_status == 3) {
++                switch ($ch) {
++                case "\\":
++                    $new .= "\\\",";
++                    $history_ch_status = 1;
++                    break;
++                case "\r":
++                    $new .= "\\\",\\r";
++                    $history_ch_status = 0;
++                    break;
++                case "\n":
++                    $new .= "\\\",\\n";
++                    $history_ch_status = 0;
++                    break;
++                case "\t":
++                    $new .= "\\\",\\t";
++                    $history_ch_status = 0;
++                    break;
++                case "\"":
++                    /* previous \", is end of the value */
++                    $new .= "\\\\\",\"";
++                    $history_ch_status = 0;
++                    break;
++                default:
++                    /* previous \", is inside a value */
++                    $new .= "\\\",";
++                    $new .= $ch;
++                    $history_ch_status = 0;
++                    break;
++                }
++            }
++        }
++        return $new;
++    }
++
 +}
 diff -urNa simplesamlphp-1.14.16/lib/AN/idpnamemap.php simplesamlphp/lib/AN/idpnamemap.php
 --- simplesamlphp-1.14.16/lib/AN/idpnamemap.php	1970-01-01 08:00:00.000000000 +0800
Index: /branches/rel_ag_9_4_5/webui/proxy/new/incVirtual/siteConfig/aaa/class.cliWrap_vAAAMSGraphAPI.php
===================================================================
--- /branches/rel_ag_9_4_5/webui/proxy/new/incVirtual/siteConfig/aaa/class.cliWrap_vAAAMSGraphAPI.php	(revision 20389)
+++ /branches/rel_ag_9_4_5/webui/proxy/new/incVirtual/siteConfig/aaa/class.cliWrap_vAAAMSGraphAPI.php	(working copy)
@@ -15,12 +15,14 @@
 // INCLUDE CLASS DEPENDANCIES
 // ========================================================================
 require_once('inc/class.anLib_baseCliWrapper.php');
+require_once('cli_define.inc');
 
 /*************************************************************************
 *
 * WRAPPER FOR CLI COMMANDS:
 *
-* (none)
+* show aaa saml msgraphapi
+* aaa saml msgraphapi "<tenant_id>" "<client_id>" "<client_secret>"
 *
 * PUBLIC FUNCTIONS:
 *
@@ -28,7 +30,6 @@
 * PRIVATE FUNCTIONS:
 *
 * setMainContent ()
-* getVSiteNmae ()
 * setFormContent ()
 * setJsAppend ()
 * setJsOnLoadStart ()
@@ -64,11 +65,6 @@
         $this->cssAppend = '';
         $this->jsOnResetAppend = '';
         // ------------------------------------------------------------
-        // Configuration file path
-        // ------------------------------------------------------------
-        $this->configFilePath = '/ca/an_lighttpd/simplesamlphp-{vsite_name}/lib/AN/GraphAPIConfig.php';
-
-        // ------------------------------------------------------------
         // Check overall authorization based on license and group
         // requirements.  This authorization point checks against a
         // merged policy based on all licenses and group features used
@@ -103,25 +99,11 @@
                     if (!empty($_POST[$this->classId . '_vs_aaa_saml_graph_api_param_client_secret'])) {
                         $client_secret = $_POST[$this->classId . '_vs_aaa_saml_graph_api_param_client_secret'];
                     }
-                    $config = array(
-                        'tenant_id' => $tenant_id,
-                        'client_id' => $client_id,
-                        'client_secret' => $client_secret,
-                    );
-                    $content = json_encode($config);
-                    $temp_out_clicmd_showInfo = cli::exec_direct('show info');
-                    $vsite_name = $this->getVSiteNmae();
-                    if (empty($vsite_name)) {
+                    $result = cli::exec_direct(CMD_AAA_SAML_MSGRAPHAPI, $tenant_id, $client_id, $client_secret);
+                    if (!isset($result->result) || $result->result != 1) {
                         $this->jsOnLoadEnd .= 'g_errStr += "' . language::translate('graph_api_param_save_failed') . '";';
                         break;
                     }
-                    $this->configFilePath = str_replace("{vsite_name}", $vsite_name, $this->configFilePath);
-                    if (file_exists($this->configFilePath)) {
-                        if (file_put_contents($this->configFilePath, $content) === false) {
-                            $this->jsOnLoadEnd .= 'g_errStr += "' . language::translate('graph_api_param_save_failed') . '";';
-                            break;
-                        }
-                    }
                     break;
                 default:
                     break;
@@ -132,18 +114,6 @@
         // ------------------------------------------------------------
     }
 
-    /*********************************************************************
-     * Get name of virtual site
-     */
-    function getVSiteNmae () {
-        $temp_out_clicmd_showInfo = cli::exec_direct('show info');
-        $vsite_name = "";
-        if ($temp_out_clicmd_showInfo->result) {
-            $vsite_name = $temp_out_clicmd_showInfo->content[1]->vsite_name;
-        }
-        return $vsite_name;
-    }
-
     /********************************************************************
     *
     * Create main HTML content for the respective CLI command
@@ -166,13 +136,11 @@
             'client_id' => '',
             'client_secret' => '',
         );
-        $vsite_name = $this->getVSiteNmae();
-        if (!empty($vsite_name)) {
-            $this->configFilePath = str_replace("{vsite_name}", $vsite_name, $this->configFilePath);
-            $get_config = file_get_contents($this->configFilePath);
-            if ($get_config !== false && !empty($get_config)) {
-                $config = json_decode($get_config, true);
-            }
+        $setting = cli::exec_direct(CMD_SHOW_AAA_SAML_MSGRAPHAPI);
+        if (!empty($setting->content) && !empty($setting->content[0])) {
+            $config['tenant_id'] = $setting->content[0]->tenant_id;
+            $config['client_id'] = $setting->content[0]->client_id;
+            $config['client_secret'] = $setting->content[0]->client_secret;
         }
 
         // ------------------------------------------------------------
