
本文显示了使用Power BI分析运行1C-Bitrix的站点上的用户访问权限的示例。
问题
随着时间的流逝,越来越多的用户以一种或另一种方式连接到Internet资源的开发,并且具有比站点普通用户更高的权限。
在这方面,控制对机密功能的访问变得越来越困难。 好吧,如果编写了有助于在或多或少安全级别上控制访问的规则。 但是,经常会发生同事搬到其他部门,按法令:)或离开而仍然存在的情况。
当然,这会带来不同的威胁:客户群的泄漏,破坏,破坏等等。
我从事的项目的年龄已经有10年了。 该数据库有成千上万的用户,其中包括数百个具有特权的用户。
本文显示了一个示例,该示例说明如何在Bitrix CMS(BUS)的控制下简化用户对各种站点对象的审核。
问题在于Bitrix管理面板无法提供获得具有访问权限的完整图片的机会。 单击一堆链接并等待管理页面加载也是不愉快的。
Power BI将用作此的主要工具(略有超出其主要目的:)
假定读者已经在基本级别上熟悉Power BI,知道SQL的基础知识,并且也知道如何使用Bitrix管理面板。 将考虑Bitrix的标准可访问性功能。
Bitrix管理面板的缺点
由于缺少与访问相关的画面-所有模块/节/信息块的摘要数据,已被授予访问权限,因此不可能在可接受的时间内在标准管理面板中进行审核。
管理员绩效:
- 在Bitrix管理面板的“用户组”部分中,有一项功能可以生成SQL查询,以选择所有具有用户数的组。 当基数较小时,一切都很好。 但是对于拥有数十万用户的数据库,以及在具有128 GB RAM的专用服务器上的数百个用户组,只需打开此部分就需要8秒钟。
- 组卡中还有一个请求,由于某种原因,它会选择所有用户组,而不是仅接收所选组的数据。 搁置损失3秒。
解决方案
通常,有几种解决方案。
- 编写提供访问网站的规则,并清楚地遵循它们。
- 定期进行访问审核。
- 希望获得最好的,而不是浪费有限的公司资源。
本文将只考虑第二种方法。
任务
- 选择工具,使您可以快速获取具有扩展权限的每个用户的访问级别的数据。
- 设置工具,使它们可以清晰显示图片,并具有必要的细节和交互性的整体访问权限。
- 进行访问审核。
在Bitrix中访问存储
Bitrix允许您通过用户组灵活地配置权限。
访问设置主要存储在MySQL表中。 某些设置存储在文件中。 例如,文件和文件夹访问权限存储在.access.php文件中。
分析用户和用户组访问:
- 信息块
- 具有访问级别的Web表单
- 具有访问级别的Web表单状态
- 网站的各个部分
- 具有访问级别的Bitrix模块
工具
- Power BI Desktop,使您可以很好地可视化数据,并从大量(几乎)源中获取数据。 实际上,可以用普通的Excel 2016及更高版本替换Power BI-PowerQuery已包含在其交付中,您可以通过它选择所有数据进行分析。 但是,Power BI允许您基于它们之间的关系以交互方式显示数据,这使您可以快速找到隐藏的依赖关系。
- MySQL连接器必须能够通过Power BI向MySQL Web服务器创建查询。
- 如果仅通过SSH打开对数据库的访问,则可以通过Kitty或Putty隧道传输到MySql。
获得以下访问方案:Power BI→MySQL连接器→Kitty→MySQL。
Power BI
Power BI Desktop-使您可以很好地可视化数据,从大量(几乎)源中获取数据。 实际上,可以用普通的Excel 2016及更高版本替换Power BI-PowerQuery已包含在其交付中,您可以通过它选择所有数据进行分析。 但是,Power BI允许您基于它们之间的关系以交互方式显示数据,这使您可以快速找到隐藏的依赖关系,这是我们进行访问修订所需要的。
您可以在
官方页面上下载它。
MySQL连接器
转到
页面 。 下载并安装。 有时,安装后您将不得不重新启动PC。
小猫/腻子
要对Bitrix数据库执行SQL查询,您将需要配置隧道。
- 输入服务器IP和端口

- 我们在SSH上锤击用户名和密码

- 我们进行端口转发:

- 我们将所做的设置保存在配置文件中以备将来使用:

- 我们开始。
您还可以下载Putty并使用以下命令运行它:
putty.exe -ssh "USER@HOST" -pw "PASSWORD" -2 -v -P 22 -L 3306:127.0.0.1:3306
自然,在更新Power BI中的数据之前,必须先运行Kitty / Putty。
用户和用户组
与许多CMS一样,Bitrix实现了一种通过用户组定界访问权限的机制。
将数据库中的实体卸载到Power BI数据模型中:
以及组与用户之间的关系。
团体
我们仅将自己限制在活跃的群体中。
组列表存储在b_group表中。
- 创建一个连接:

- 输入:
- 在“服务器:本地主机:3306”字段中
- 在“数据库:bitrix_db”字段中(Bitrix使用的数据库名称)
- SQL查询:
SELECT id, timestamp_x, active, name, description, anonymous FROM b_group WHERE active = 'Y';

- 输入数据库的登录名和密码并发送请求:



- 立即给请求起一个友好的名字:

- 我们以表格形式在单独的工作表上列出组:

对于与Bitrix数据库有关的其他查询,这种提取和呈现数据的方法将类似。
用户数
现在,卸载所有具有高级权限的用户。 但是,您不应该卸载仅包含在不授予用户任何其他权限的组中的用户,例如“所有用户,包括未注册的用户”(值得注意的是,此组与用户的连接是为版本12之前注册的所有用户存储的。版本,则该组被认为是系统性的,并且不存储与数据库用户进行通信时的数据。
我们仅将自己限制为激活的用户。
为此,您需要:
- 选择授予扩展权限的组的所有ID。 这是节省流量的必要步骤,因为 b_user_group中的条目数可以达到数百万,具体取决于项目的复杂性。
- 创建用于卸载链接的动态请求用户-组
- 卸载具有从子句2链接的用户。
让我们开始:
- 调用查询编辑器:主页→编辑查询
- 让我们创建一个指向“组”初始请求的链接:

- 将新请求重命名为“ Group ID”,并从安全角度仅选择那些有趣的组。

- 现在我们得到一行,其中包含用逗号分隔的组ID:
- 添加自定义列:AddColumn→常规→自定义列

- 删除除ID和分组以外的所有列:

- 按“分组”列分组:


- 添加另一列,如下所示:

- 让我们展开列表,以便用逗号分隔值:

- 并进入结果单元格:

- 然后,Power BI将查询转换为可在动态SQL查询中使用的变量:

- 让我们创建一个包含用户与组之间关系的“用户组”请求,类似于“组”部分中的操作。
SQL查询:
SELECT ug.user_id, ug.group_id FROM b_user_group ug JOIN b_group g ON g.id = ug.group_id JOIN b_user u ON u.id = ug.user_id WHERE g.ACTIVE = 'Y' AND u.ACTIVE = 'Y' AND ug.group_id IN ();
XXX将需要替换为组ID,并用逗号分隔。
- 我们将调用编辑请求的源并将其替换为以下内容:
let sql = "SELECT ug.user_id, ug.group_id #(lf)FROM b_user_group ug #(lf)JOIN b_group g ON g.id = ug.group_id #(lf)JOIN b_user u ON u.id = ug.user_id #(lf)WHERE g.ACTIVE = 'Y' #(lf) AND u.ACTIVE = 'Y' #(lf) AND ug.group_id IN ("&#"ID "&");", Source = MySQL.Database("localhost:3306", "bitrix_db", [ReturnSingleDatabase=true, Query=sql, CreateNavigationProperties=false]) in Source
- 之后,您会收到以下警告:
Formula.Firewall: Query '-' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
要摆脱它,您需要更改隐私级别:


之后,更新查询。 - 我们使用与“组ID”相同的方式来创建变量“用户ID”(也就是说,我们根据“用户”请求进行链接等)。 使用它,我们将生成一个SQL查询,该查询允许我们仅选择分析所需的用户。 首先删除重复的user_id:

- 我们创建一个选择用户的请求,类似于对“用户组”的请求。
SQL: SELECT id, last_name, NAME, email, date_register, last_login FROM b_user WHERE active = 'Y' AND id IN ( );
XXX将需要替换用户ID。
建立请求之间的关系
为了使Power BI以交互方式筛选不同视图中的数据,您需要定义查询之间的关系。 在我们的例子中,我们需要连接字段:
- “用户组” [group_id]→“组” [id]
- “用户组” [user_id]→“用户” [id]

同样,我们将绑定其他查询。
用户和用户组报告
在“报告”选项卡上,我们使用“表”作为可视化元素来显示用户和组的列表。
从“用户”请求中,选择字段:last_name,名称,last_login,电子邮件。
从“用户组”请求中,选择group_id字段。
因为 由于我们在请求之间分配了连接,因此Power BI将能够正确使用聚合功能Count来计数每个用户所属的组数。

接下来,添加另一个表,然后从“组”请求中选择“名称”字段,并从“用户组”请求中选择“ user_id”字段-为其设置“计数(不同)”聚合以查看该组中的用户数。
因为 “组”和“用户”请求通过关联的“用户组”请求连接,然后,在具有组列表的表中单击用户时,将仅显示包含所选用户的那些组。 反之亦然。

这样,您可以单击每个用户并查看其所属的组,也可以单击组并查看哪些用户是组的一部分。 好吧,然后做出有关更改用户访问权限的决定。
下面介绍如何将其余表放置在Power BI常规报告中,因为 这是通过类似的方式完成的。
.access.php
在Bitrix中,您可以通过在.access.php文件中指定组号和所需的访问级别来设置对文件夹和文件的访问。
我们的任务是将分散在项目服务器周围的所有.access.php文件中的数据减少到表格视图中。
为此:
- 我们从服务器搜索并存档所有.access.php文件,并保存这些文件的路径。
我使用terminalka搜索,复制和存档找到的文件。 命令示例:
find “BITRIX_PROJECT_DIR” -name '.access.php' -type f > “OUTPUT_DIR/.access.php.files.txt”&&tar cvfpz “OUTPUT_DIR/.access.php.files.tar” -T “OUTPUT_DIR/.access.php.files.txt”&&find “OUTPUT_DIR” -type d -exec chmod 775 {} \; && find “OUTPUT_DIR” -type f -exec chmod 775 {} \;&&find “OUTPUT_DIR” -type d -exec chown bitrix:bitrix {} \; && find “OUTPUT_DIR”/ -type f -exec chown bitrix:bitrix {} \;
在这里:
- BITRIX_PROJECT_DIR-Bitrix上项目所在的文件夹。
- OUTPUT_DIR-将放置找到包含.access.php列表的.access.php.files.txt文件以及包含所有找到的.access.php副本的.access.php.files.tar存档的文件夹的路径。
自然,如果有许多项目(使用了多站点),则我们选择一个包含所有项目的文件夹。 - 在Power BI项目旁边的某个位置下载并解压缩.access.php存档。
我编写了一个自动执行此操作的批处理文件:下载是通过wget实现的; 通过7zip-解压缩。
批处理文件示例:

包含批处理文件设置的文件:

现在创建一个查询,该查询将以表格形式汇总所有.access.php的内容。
- 为了方便起见,创建一个参数,该参数将包含我们要从其中提取所有.access.php内容的文件夹的路径。

- 我们将选择“文件夹”类型的请求,然后选择我们的参数作为路径:

- 展开内容字段:

XXXXXXX是列分隔符;从所有文件导入数据后,您需要一个列。 - 之后,Power BI将删除我们需要的列,其中包含.access.php的路径。 因此,我们需要编辑“删除其他列1”步骤,在其中选择“文件夹路径”:

- 保留以下列:Folder Path和Column1。
- 要从文件夹路径中删除本地文件的绝对路径,请使用替换:

- .access.php文件包含以下格式的访问设置:
$PERM[""]["ID "] = "< >";
我们的任务是分散以下列:路径,组ID,访问级别。 这是通过使用过滤器,列分隔(拆分列)和自定义列(自定义列)完成的。 - 结果应为下表:

正如您在组ID字段中看到的那样,有“ *”(所有人均可访问)。 为了能够指定与其他请求的连接,我们需要将此字段设置为整数,而不会丢失有关“ *”的信息(对于所有组而言)。 让我们发出两个请求,例如到原始DotAccessPhp请求的“链接”:
- 第一个DotAccessPhpForRels将仅包含整数组ID(我们通过删除组ID列中的*来使用过滤器)-我们将其与其余请求连接:

- 第二个-DotAccessPhpForAll-仅*(使用过滤器)。
接线图:

要在其他视图中从DotAccessForRels选择文件时仅显示相关数据,请将“交叉过滤器方向”参数更改为“双向”:

对于将在下面添加的其他请求,这也需要完成。
信息块
您需要卸载信息块列表和信息块链接组表。
我们将仅上传有关活动信息块的信息。
- 我们创建请求“ Infoblocks”。 SQL查询:
SELECT i.id, i.NAME '', i.TIMESTAMP_X ' ', GROUP_CONCAT(ist.SITE_ID SEPARATOR ', ') '' FROM b_iblock i JOIN b_iblock_site ist ON ist.IBLOCK_ID = i.id GROUP BY 1,2,3; “-”: SELECT ig.iblock_id, ig.group_id, ig.permission FROM b_iblock_group ig JOIN b_group g ON g.id = ig.group_id JOIN b_iblock i ON i.ID = ig.IBLOCK_ID WHERE g.ACTIVE = 'Y' AND i.ACTIVE = 'Y';
- 我们更新了通信方案,不要忘记将“交叉滤波器方向”参数更改为“两者”:

表格
对于表单,用户组的权限既授予表单本身,也授予表单填写结果所处的状态。
- 创建“表格”请求:
SELECT f.ID, f.name '', GROUP_CONCAT(f2s.SITE_ID SEPARATOR ', ') '' FROM b_form f JOIN b_form_2_site f2s ON f2s.FORM_ID = f.ID GROUP BY 1, 2 ORDER BY 2;
- 创建一个请求“表单组”:
SELECT DISTINCT f2g.group_id, f2g.form_id, f2g.PERMISSION ' ' FROM b_form_2_site f2s JOIN b_form_2_group f2g ON f2g.FORM_ID = f2s.FORM_ID JOIN b_group g ON g.ID = f2g.group_ID WHERE g.ACTIVE = 'Y' ORDER BY 1, 2, 3;
- 我们创建请求“表单状态”。
SELECT fs.ID, fs.TITLE '', fs.form_id FROM b_form_status fs JOIN b_form f ON f.ID = fs.FORM_ID WHERE fs.ACTIVE = 'Y' AND EXISTS (SELECT f2s.FORM_ID FROM b_form_2_site f2s WHERE f2s.FORM_ID = f.ID LIMIT 1) ORDER BY 3, 2;
- 创建请求“表单组状态”
SELECT fs2g.status_id, fs2g.group_id, fs2g.PERMISSION '' FROM b_form_status_2_group fs2g JOIN b_form_status fs ON fs.ID = fs2g.STATUS_ID JOIN b_group g ON g.ID = fs2g.group_ID JOIN b_form f ON f.ID = fs2g.GROUP_ID JOIN b_form_2_site f2s ON f2s.FORM_ID = f.ID WHERE fs.ACTIVE = 'Y' AND (g.ACTIVE = 'Y') ORDER BY 1, 2, 3;
- 更新连接方案:

模组
- 我们创建一个请求“模块组”。
SELECT mg.MODULE_ID '', mg.group_id, mg.G_ACCESS '', t.LETTER, t.NAME FROM b_module_group mg JOIN b_group g ON g.id = mg.GROUP_ID LEFT JOIN b_task t ON t.MODULE_ID = mg.MODULE_ID AND t.BINDING = 'module' WHERE g.active = 'Y' AND mg.G_ACCESS = t.LETTER;
- 更新通讯:

计分板
我们自定义表格样式,最大限度地利用可用空间。
结果应该类似于以下内容:

稍作修改的记分板(表中的元素数):

顺便说一句,首先配置一个表的外观,然后使用Home→Format Painter简单地将其视图应用于其他表是很方便的。 此功能的作用方式与Word和Excel(按样本设置格式)中的作用相同。
管理员连结
为了可以快速访问网站并在管理面板中进行设置,可以使用DAX语言添加自定义列并将其设置为“ Web URL”。 为此,选择创建的列并分配适当的类型(建模→属性→数据类别→Web URL)。
组请求的示例:

在视图中添加一列:

现在,您只需单击表格单元格,然后转到Bitrix管理面板中的组卡。
文件报告
为了方便起见,您可以通过在表上放置有关访问Internet资源的文件和部分的表格来制作单独的报告:

该报告还添加了直接通过Bitrix管理面板编辑所有.access.php的链接。
总结
Bitrix在具有明显优点和缺点的cms怪兽中是冠军,其外表美丽而内表可怕。 它没有便捷的访问管理工具。 但是这个问题是在免费工具的帮助下解决的,而没有吸引宝贵的程序员时间。
这种方法的优点还包括能够使用Bitrix的其他信息快速补充Power BI中的模型,例如,某人想知道何时创建或更改.access.php以及其他文件。
现在,在构建访问权限模型并在Power BI中将其可视化之后,就足够了:
- 持续单击用户,组,表单,文件,并实时查看有关访问的所有连接;
- 快速进入必要的管理页面进行编辑;
- 直接在Power BI中使用最新的Bitrix数据更新数据模型。
结果,进行了审核,并调整了用户访问权限。
PS在市场上有一个免费的模块“访问控制中心”,但是它非常有限,对它的最后评论是5年多了。 也许有人会喜欢在Bitrix中构建这样的仪表板的想法,然后将其实现为模块...
PS2。 如果有人对使用Power BI解决在各种会计系统中查找隐藏的依赖关系的问题感兴趣,请在注释中编写。 然后,我将针对该主题再写几篇文章。
PS3 感谢我的同事帮助我撰写本文:Alexander Voronkov,Evgeny Shapochkin,Alexei Titov。