- cacti前端构成
- 1 index页面
- 2 includeauthphp
- 3 includetop_headerphp
- 4 includebottom_footerphp
- 5 globalphp页面
1 cacti前端构成
cacti首先进入的就是index页面,所以从index页面看起。
1.1 index页面
包含了下面两个页面
1. include(“./include/auth.php”);
2. include(“./include/top_header.php”);
3. api_plugin_hook(‘console_before’);
4. 登陆默认首页的绘制。
5. api_plugin_hook(‘console_after’);
6. include(“./include/bottom_footer.php”);
关于第4点:
默认的index页面使用top_header绘制了出了bottom以及main_content之外的所有地方,具体可以参考top_header讲解
在结束了index的绘制之后,所有的menu,tab等集中在top_header.php中所绘制的
api_plugin_hook(‘top_header_tabs‘);
以及
draw_menu()中
一个是header的tab标签。
一个是左边的menu。
现在在看完了cacti的边缘绘制问题,让我们先来看下menu所连接的各个页面所产生的业务功能。这个可以通过已经搭好的cacti主页面来观察来查询各个menu所对应的php页面,然后我们对下述页面依次做介绍。
1.2 include\auth.php
- include(“./include/global.php”); 请参考global页面
- 检测是否是这是新的未安装cacti项目
- 验证auth_method,auth_method包含3种验证方式,介绍见下文
如果auth_method>0,也就是需要验证的话,api_plugin_hook_function(‘auth_alternate_realms’);
3种验证方式:
None - No authentication will be used, all users will have full access. 对应auth_method为0
Builtin Authentication - Cacti handles user authentication, which allows you to create users and give them rights to different areas within Cacti. 对应auth_method为1
Web Basic Authentication - Authentication is handled by the web server. Users can be added or created automatically on first login if the Template User is defined, otherwise the defined guest permissions will be used. 对应auth_method为2
验证步骤讲解:
$guest_account验证是否是guest用户,如果不是在观察$_SESSION["sess_user_id"]是否为空,为空的话就返回login页面,auth_login.php,否则根据当前$realm_id查询user_auth_realm表,
查询是否有权限查看,没有的话就会返回一个auth_deny.gif的图片,然后exit()掉。
如何获取当前$realm_id:
$realm_id = $user_auth_realm_filenames{basename($_SERVER["PHP_SELF"])};
对于第3步的read_config_option:方法说明
下述已传入config_name为auth_method为例:
read_config_option定义于function.php中,
首先读取了$config以及$database_default两个全局变量。
然后去settings表中根据传入的config_name去查询指定的settings记录,
if 有的话就设置config_array[config_name]的值为改记录的value值
else read_default_config_option(config_name)
对于read_default_config_option的说明:
read_default_config_option同样位于functions.php中,它是读取$settings这个全局变量中的二层数组中名字为auth_method的default属性,打开global_settings.php查询auth_method,我们可以看到该方法定义于authentication数组的auth_method。default为1
综上我们可以知道最后得到的read_config_option("auth_method")值为1.
1.3 include/top_header.php
这个页面主要负责添加js文件,后期自己做的js文件可以考虑放到这里。这个页面的工作包含如下,请结合下面图片一起参照:
最外层花了
body中间定义了一个table
<table width="100%" cellspacing="0" cellpadding="0">.
这个最外层table的内部包含了3个主要的tr,下面讲述着3个tr分别的作用:
1. 绘制了console和graph
2. 绘制了logged in
通过从$_SESSION["sess_user_id"]以及user_auth表获取到用户名:db_fetch_cell("select username from user_auth where id=" . $_SESSION["sess_user_id"])
3. 绘制了左边的menu,
通过draw_menu()方法。
通过从$_SESSION["sess_user_id"]以及user_auth_realm表中获取到用户有权限的范围区域$user_realms,然后通过之前的global_array.php页面中早就已经存好的$menu全局变量,并根据$user_realms绘制出可以显示的menu集合。
最后插了一张仙人掌的图片链接到about.php。
但是可以看到 table并没有绘制结束?
table还有tr要继续绘制,这个content就是main_content,例如index.php就是
<table width="100%" align="center">
<tr>
<td class="textArea">
<strong>You are now logged into <a href="about.php">Cacti</a>. You can follow these basic steps to get
started.</strong>
<ul>
<li><a href="host.php">Create devices</a> for network</li>
<li><a href="graphs_new.php">Create graphs</a> for your new devices</li>
<li><a href="graph_view.php">View</a> your new graphs</li>
</ul>
</td>
<td class="textArea" align="right" valign="top">
<strong>Version <?php print $config["cacti_version"];?></strong>
</td>
</tr>
</table>
这一段代码
那么如果是graph的话,就是graph.php里面的table内容。
1.4 include/bottom_footer.php
绘制了结束标签,如果有分页并且main_content是处于插件的content时,可能还会涉及到分页的绘制。
1.5 global.php页面
- (具体配置在下面的config.php中)默认的数据库的基本配置
- $cacti_session_name
- (具体配置在下面的config.php中)默认的$url_path
- include(dirname(FILE) . “/config.php”); 最后生效的配置文件
- $no_http_header_files的设置
- $config的设置
- $colors的设置
- 清除了所有的register_globals,such as “_GET”,”_POST”
- 包含了很多的lib库以及include下的文件,下面来看看都有lib和include中部分php文件及其作用。
- 熟悉的api_plugin_hook(“config_insert”);调用我们的所有自定义插件中的config_insert方法。
global包含了页面的全局变量以及工具类的初始化。
lib:
file name | function |
---|---|
database.php | 定义了很多数据库操作,例如db_connect_real,db_close等 |
functions.php | 定义了很多功能型函数,例如title_trim,read_graph_config_option等 |
plugins.php | 定义了很多和plugin相关的功能型函数,例如do_hook,do_hook_function等 |
html.php | 包含了所有组装控件的方法,即function |
html_form.php | 包含了所有组装包含form控件的方法,即function |
html_utility.php | html工具类 |
html_validate.php | html表单验证类 |
variables.php | 主要是一个变量处理类,用于把各处的变量替换为有实际意义的常量 |
auth.php | 是一个用户权限判断的工具类 |
include:
file name | function |
---|---|
global_constants.php | 定义了项目中常用的常量 |
plugins.php | 定义了项目中使用plugin的函数use_plugin,创建了$plugin_hooks, $plugins_system, $plugins等全局变量 |
global_arrays.php | 定义了项目以及pa的全局数组,其中pa包含数组为menu和realms |
global_settings | 定义了全局设置 |
global_form.php | 包含各个页面所用到的form表单array |
需要注意的地方是lib下的auth.php
记录以上的信息方便后期对用户系统的调整
1. 其中包含了一个user_copy方法,从这个方法中可以看出,用户所拥有的数据包含如下表:
*user_auth
*user_auth_perms
*user_auth_realm
*settings_graphs
*settings_tree
最后
api_plugin_hook_function(‘copy_user‘, array(‘template_id‘ => $template_id, ‘new_id‘ => $new_id));
关于这个api_plugin_hook_function我们已经十分熟悉,就是用来刷新用户插件的信息的,再次调用我们自定义的插件并实现了copy_user的hook的方法。
2. user_disable,user_enable方法,从这个方法中我们可以知道判断用户是否是禁用是通过enabled字段,为空就是禁用,为"on"就是启用。
3. get_graph_permissions_sql & get方法,从这个方法中我们可以知道对于graph权限的限制是由以下表作用的
*graph_templates_graph 图片表
*graph_local 图片与host以及snmp映射表
*host host表,也就是device数据表
*graph_templates 图片模版表
*user_auth_perms 用户权限细节表
*user_auth 用户权限表
sql如下:
$graphs = "select
graph_templates_graph.local_graph_id
from (graph_templates_graph,graph_local)
left join host on (host.id=graph_local.host_id)
left join graph_templates on (graph_templates.id=graph_local.graph_template_id)
left join user_auth_perms on
((graph_templates_graph.local_graph_id=user_auth_perms.item_id
and user_auth_perms.type=1
and user_auth_perms.user_id=" . $_SESSION["sess_user_id"] . ") OR
(host.id=user_auth_perms.item_id
and user_auth_perms.type=3
and user_auth_perms.user_id=" . $_SESSION["sess_user_id"] . ") OR
(graph_templates.id=user_auth_perms.item_id
and user_auth_perms.type=4
and user_auth_perms.user_id=" . $_SESSION["sess_user_id"] . "))
where graph_templates_graph.local_graph_id=graph_local.id
" . (empty($sql_where) ? "" : "and $sql_where") . "
and graph_templates_graph.local_graph_id=$local_graph_id
group by graph_templates_graph.local_graph_id");
$sql_where可以自行去查看。
由上面的sql可以看出,对于graph的权限是由3个板块控制的
Graph
Device
Graph Template
回到user_auth_perms这个表,
当type为1时:graph_templates_graph.local_graph_id=user_auth_perms.item_id
当type为3时:
host.id=user_auth_perms.item_id
当type为4时
graph_templates.id=user_auth_perms.item_id
$sql_where:
(and user_auth_perms.type != 1 OR user_auth_perms.type is null)
这是去查询user_auth表取出三个字段
*policy_graphs,
*policy_hosts,
*policy_graph_templates
if ($policy_graphs == "1") {
$sql_policy_and .= "$sql_and(user_auth_perms.type != 1 OR user_auth_perms.type is null)";
}elseif ($policy_graphs == "2") {
$sql_policy_or .= "$sql_or(user_auth_perms.type = 1 OR user_auth_perms.type is not null)";
}
从上面的语句大概可以看出当判断
Graph
Device
Graph Template
的时候,当policy_graphs为1的话,可以不用考虑user_auth_perms.type里面的type为1的字段,为2的话就需要对user_auth_perms.type为1的数据进行考虑。
4. 对于is_tree_allowed方法分析和上面的一样
这个是用户graph permission板块的最后一项。
Tree
sql如下:
"select policy_trees from user_auth where id=" . $_SESSION["sess_user_id"]
判断如下:
if ((sizeof($trees) > 0) && ($current_user["policy_trees"] == "1")) {
return false;
/* policy == deny AND matches = ALLOW */
}elseif ((sizeof($trees) > 0) && ($current_user["policy_trees"] == "2")) {
return true;
/* policy == allow AND no matches = ALLOW */
}elseif ((sizeof($trees) == 0) && ($current_user["policy_trees"] == "1")) {
return true;
/* policy == deny AND no matches = DENY */
}elseif ((sizeof($trees) == 0) && ($current_user["policy_trees"] == "2")) {
return false;
}
由上面的判断可知和前三个model的原理一样,这里不再赘述。
user_auth页面
查询version表中是否有版本信息,没有返回install页面,
$_SESSION[“sess_config_array”]
read_config_option方法查看config全局变量,没有查询数据库的settings表,在没有read_default_config_option()查询global_settings中的$settings
php的function可以设置默认值
官方使用的几个有用的函数
1. (html_form.php)
2. (html.php)
3. global_settings.php存放setting的键值对(default value) settingsgraphs3.inputvalidateinputnumber4.getrequestvar5.list(key,value)和each()一起使用是将数组当前指针所指向单元的键/值对分别赋值给变量key,valueuseradmin.php853while(list(field_name, fieldarray)=each(tab_fields)) {}
function | explain |
---|---|
$_SERVER[‘PHP_SELF’] | /test.php/123456 |
$_SERVER[‘SCRIPT_NAME’] | /test.php |
basename() | basename(/znms-test/index.php) = index.php |
in_array(param1,param2,param3) | / |
header (“Location:index.php”) | 跳转页面 |
gmdate($format,$timestamp=null) | Format a GMT/UTC date/time |
session_name($name = null) | Get and/or set the current session name |
session_start () | Initialize session data |
session_unset () | Free all session variables |
session_destroy () | Destroys all data registered to a session |
ini_get ($varname) | Gets the value of a configuration option in php.ini |
unset($var) | Destroys the specified variables |
list($var1, …$_) | list($a, $b, $c) = $my_array; |
die() | 函数输出一条消息,并退出当前脚本。 |
custom method
function | explain |
---|---|
draw_edit_form | 绘制edit表单 |
inject_form_variables(&$form_array, $arg1 = array(), $arg2 = array(), $arg3 = array(), $arg4 = array()) | inject_form_variables - replaces all variables contained in $form_array with their actual values |
1.
\$_SERVER[‘PHP_SELF‘] = /test.php/123456
而\$_SERVER[‘SCRIPT_NAME‘] = /test.php
所以为了安全起见,为了指向自身,应该用\$_SERVER[‘SCRIPT_NAME‘]而不是\$_SERVER[‘PHP_SELF‘]。
- 后期汉化工作可以从global开头的表中入手,可以提取出一些未汉化并插入在散碎php页面。
- 后期的用户管理工作可以参考一下auth.php来了解到用户的具体构成
- user_auth
- user_auth_perms
- user_auth_realm
- settings_graphs
- settings_tree
- 待添加