第 5 章 定制

目录

访问控制列表(ACL)
介绍
定义
示例
ACL设置参考
流程管理
介绍
流程示例
记录需求
经理审批
采购部处理
收发室处理
实施示例
流程(作为容器)
活动对话框
转换
转换操作
活动
书籍采购流程路径
流程配置参考
流程
活动
活动对话框
转换
转换操作
访问控制列表(ACL)
导入即开即用的流程
导入
OTRS前端界面的本地化

访问控制列表(ACL)

介绍

从OTRS 2.0开始,访问控制列表(ACL)能用来控制到工单、模块、队列等的访问权限,或在某些状况下影响工单操作(关闭、转移等)。ACL可以作为现有系统权限角色的补充。使用ACL在系统中映射基本的基于工单属性的工作流。

一般来说,ACL用基于一个预定义的规则集来减少一个工单可能的选项。

ACL定义可以直接写入文件 Kernel/Config.pm。但是现在不再推荐这种方式,因为在系统管理面板Access Control Lists访问控制列表图形界面允许首先将ACL保存到数据库中,然后在准备使用时部署到一个文件。

本章有一些ACL示例可以帮助你熟悉定义ACL的流程,还有ACL所有可能重要的设置的参考说明。

警告

默认用户‘root@localhost’不受工单ACL的影响。

定义

ACL定义可以拆分为两大部分:‘匹配’和‘修改’。在ACL匹配部分包含用来满足使用ACL的属性,如果ACL中定义的属性不匹配传递过来的属性,则ACL不会产生任何影响,但匹配了ACL就会产生影响。修改部分包含减少工单可能选项的规则。

匹配部分

  • 属性

    本部分包含可动态修改的匹配选项。例如:在一个工单创建时随着服务人员设置工单信息而动态修改工单数据。如果一条ACL匹配了一个工单属性,则只有当匹配的属性被选择时ACL将会激活并可能减少其它的工单属性,但只要选择了另一个值,ACL就不会产生任何影响。

  • PropertiesDatabase数据库中的属性

    本部分类似于属性,但不会更改未保存到数据库中的工单属性,这意味着更改属性而不提交将不会产生任何影响。 本部分内容不用于创建工单屏幕(因为工单尚未在数据库中创建)。

更改部分

  • Possible(可能的)

    ‘可能的’部分重置数据,以便将数据减少为只有在本部分列出的元素。

  • PossibleAdd(添加可能的)

    在‘添加可能的’部分的元素添加因在其它ACL减少而缺失的元素。‘添加可能的’只能连同其它有‘可能的’或‘不可能的’部分的ACL使用。

  • PossibleNot(不可能的)

    本部分用于从当前数据中移除特定元素。它可以单独使用,也可以与连同其它有‘可能的’或‘添加可能的’部分的ACL使用。

为了使ACL的开发更容易且更强大,每个部分还有一些所谓的属性‘修改器’。这个修改器的解释如下:

修改器

  • [Not]非

    这个修改器用来取反一个值,例如:有关工单优先级的'[Not]2-低',与以下结果相同:'1-非常低'、 '3-正常'、 '4-高'、 '5-非常高'。

  • [RegExp]正则表达式(区分大小写)

    用来定义一个正则表达式以匹配多个值,例如:关于工单优先级的 '[RegExp]low'就是 '1 very low'、 '2 low'。

  • [regexp]正则表达式(忽略大小写)

    它与[RegExp]正则表达式(区分大小写)很相似,但它是不区分大小写的。

  • [NotRegExp]-正则表达式取反

    对正则表达式取反,如关于工单优先级的'[NotRegExp]低'就相当于是'3-正常'、'4-高'、'5-非常高'。

  • [Notregexp]-正则表达式取反(忽略大小写)

    它与[NotRegExp]-正则表达式取反很相似,但它是不区分大小写的。

示例

下面的示例按图形界面和文本格式两种方式展示。

例 5.1. 仅允许工单优先级5的工单转移到一个队列的ACL。

本示例为你展示一条ACL的基本结构。首先,ACL需要有一个名称。本案例中,ACL的名称是“100-Example-ACL”。注意:ACL在执行前会按数字排序,所以你要斟酌命名。

其次,你要有一个“Properties属性”部分作为工单的过滤器。这部分的所有条件都用来确定ACL是否适用或不适用一个工单。在我们的示例中,如果工单在队列“RAW”中且优先级为“5-非常高”就匹配ACL,这还会受屏幕中数据变更的影响(例如:此时工单在队列“RAW”中且优先级为“3-正常”就不会匹配ACL,但随后选择了优先级下拉菜单并将优先级变更为“5-非常高”后就匹配了ACL)。

最后,“Possible可能的”部分定义屏幕中的修改内容。在本示例中,在工单屏幕可用的队列只能选择队列“Alert”。

图 5.1. ACL 100-Example-ACL

ACL 100-Example-ACL


# ticket acl
$Self->{TicketAcl}->{'100-Example-ACL'} = {
    # match properties
    Properties => {
        # current ticket match properties
        Ticket => {
            Queue => ['Raw'],
            Priority => ['5 very high'],
        }
    },
    # return possible options (white list)
    Possible => {
        # possible ticket options (white list)
        Ticket => {
            Queue => ['Alert'],
        },
    },
};
                


例 5.2.  ACL仅允许已保存到数据库中的优先级为5的工单移到到一个队列。

本示例与上一个示例很相似,但本示例仅匹配已保存到数据库在队列“Raw”中且优先级为“5-非常高”的工单。这种ACL在工单的修改内容真正更新到数据库之前不会在屏幕中对工单有任何修改。

图 5.2. ACL 102-Example-ACL

ACL 102-Example-ACL


# ticket acl
$Self->{TicketAcl}->{'102-Example-ACL'} = {
    # match properties
    PropertiesDatabase => {
        # current ticket match properties
        Ticket => {
            Queue => ['Raw'],
            Priority => ['5 very high'],
        }
    },
    # return possible options (white list)
    Possible => {
        # possible ticket options (white list)
        Ticket => {
            Queue => ['Alert'],
        },
    },
};
                


例 5.3.  ACL禁止关闭‘Raw’队列的工单,并隐藏“关闭”按钮。

在这里可以看到一个工单字段(状态)用多个可能值过滤选择。还可以限制某些工单能够执行的操作。在本示例中,工单不能被关闭。

图 5.3. ACL 102-Second-Example-ACL

ACL 102-Second-Example-ACL


$Self->{TicketAcl}->{'102-Second-Example-ACL'} = {
    # match properties
    Properties => {
        # current ticket match properties
        Ticket => {
            Queue => ['Raw'],
        }
    },
    # return possible options (white list)
    Possible => {
        # possible ticket options (white list)
        Ticket => {
            State => ['new', 'open', 'pending reminder'],
        },
    },
    # return also not possible options (black list)
    PossibleNot => {
        # not possible action options
        Action => [ 'AgentTicketClose' ],
    },
};
                


例 5.4. ACL总是移除‘成功关闭’状态。

本示例展示如何定义取反过滤器(移除‘成功关闭’状态)。还可以看到没有定义工单属性将匹配任意工单,如ACL总是被应用到工单。如果你要默认隐藏某些值时很有用,只在特殊情况下启用这些值(例如在特殊组中的服务人员)。

图 5.4. ACL 103-Third-ACL-Example

ACL 103-Third-ACL-Example


$Self->{TicketAcl}->{'103-Third-ACL-Example'} = {
    # match properties
    Properties => {
        # current ticket match properties (match always)
    },
    # return possible options
    PossibleNot => {
        # possible ticket options
        Ticket => {
            State => ['closed successful'],
        },
    },
};
                


例 5.5.  ACL为创建在以“HW”开头的队列中的工单仅显示硬件服务。

本示例还展示了如何使用正则表达式来匹配工单和过滤可用选项。

图 5.5. ACL 104-Only-Hardware-Services-for-HW-Queues-ACL

ACL 104-Only-Hardware-Services-for-HW-Queues-ACL


$Self->{TicketAcl}->{'104-Only-Hardware-Services-for-HW-Queues-ACL'} = {
    # match properties
    # note we don't have "Ticket => {" because there's no ticket yet
    Properties => {
    Queue => {
        Name => ['[RegExp]HW'],
        }
    },
    # return possible options
    Possible => {
        # possible ticket options
        Ticket => {
            Service => ['[RegExp]^(Hardware)'],
        },
    },
};
                


例 5.6.  ACL使用CustomerID禁用客户界面的一个流程。

图 5.6. ACL 105-Disallow-Process-For-CustomerID

ACL 105-Disallow-Process-For-CustomerID


$Self->{TicketAcl}->{"105-Disallow-Process-For-CustomerID"} = {
    'Possible' => {},
    'PossibleNot' => {
        'Process' => [
            'P14'
        ]
    },
    'Properties' => {
        'CustomerUser' => {
            'UserCustomerID' => [
                'CustomerID'
            ]
        }
    },
    'PropertiesDatabase' => {},
    'StopAfterMatch' => 0
};
                


ACL设置参考

下面的示例列出了能用于ACL的所有参数。

关于流程工单如何使用ACL的详细描述,请参阅流程管理那一章的访问控制列表(ACL)部分

例 5.7. 所有可能的重要ACL设置的参考。

# ticket acl
$Self->{TicketAcl}->{'200-ACL-Reference'} = {
    # match properties (current values from the form)
    # 匹配属性(屏幕中的当前值)
    Properties => {

        # the used frontend module
        Frontend => {
            Action => ['AgentTicketPhone', 'AgentTicketEmail'],
        },

        # the logged in agent登录的服务人员
        User => {
            UserLogin => ['some login'],
            Group_rw => [
                'hotline',
            ],
            Role => [
                'admin',
            ],
            # ...
        },

        # the logged in customer登录的客户
        CustomerUser => {
            UserLogin => ['some login'],
            UserCustomerID => ['some customer id'],
            Group_rw => [
                'hotline',
            ],
            # ...
        },

        # process properties流程属性
        Process => {
            ProcessEntityID        => ['Process-9c378d7cc59f0fce4cee7bb9995ee3eb'],         # the Process that the current ticket is part of
            ActivityEntityID       => ['Activity-f8b2fdebe54eeb7b147a5f8e1da5e35c'],        # the current Activity of the ticket
            ActivityDialogEntityID => ['ActivityDialog-aff0ae05fe6803f38de8fff6cf33b7ce'],  # the current ActivityDialog that the Agent/Customer is using
        },

        # ticket properties工单属性
        Queue => {
            Name     => ['Raw'],
            QueueID  => ['some id'],
            GroupID  => ['some id'],
            Email    => ['some email'],
            RealName => ['OTRS System'],
            # ...
        },
        Service => {
            ServiceID => ['some id'],
            Name      => ['some name'],
            ParentID  => ['some id'],
            # ...
        },
        Type => {
            ID   => ['some id'],
            Name => ['some name'],
            # ...
        },
        Priority = {
            ID   => ['some id'],
            Name => ['some name'],
            # ...
        },
        SLA = {
            SLAID    => ['some id'],
            Name     => ['some name'],
            Calendar => ['some calendar'],
            # ...
        },
        State = {
            ID       => ['some id'],
            Name     => ['some name'],
            TypeName => ['some state type name'],,
            TypeID   => ['some state type id'],
            # ...
        },
        Owner => {
            UserLogin => ['some login'],
            Group_rw => [
                'some group',
            ],
            Role => [
                'admin',
            ],
            # ...
        },
        Responsible => {
            UserLogin => ['some login'],
            Group_rw => [
                'some group',
            ],
            Role => [
                'admin',
            ],
            # ...
        },
        DynamicField => {
            # Names must be in DynamicField_<field_name> format.名称必须是DynamicField_<field_name>格式。
            # Values in [ ... ] must always be the untranslated internal data keys
            #   specified in the dynamic field definition and
            #   not the data values shown to the user.
            #[...]中括号里的值必须是没有翻译的定义动态字段的内部数据,而不是显示给用户看的数据。
            DynamicField_Field1          => ['some value'],
            DynamicField_OtherField      => ['some value'],
            DynamicField_TicketFreeText2 => ['some value'],
            # ...
        },
        # alternatively, ticket properties can be specified in the ticket hash或者,可以用工单哈希表来指定工单属性
        Ticket => {
            Queue                => ['Raw'],
            State                => ['new', 'open'],
            Priority             => ['some priority'],
            Lock                 => ['lock'],
            CustomerID           => ['some id'],
            CustomerUserID       => ['some id'],
            Owner                => ['some owner'],
            DynamicField_Field1  => ['some value'],
            DynamicField_MyField => ['some value'],
            # ...
        },
    },

    # match properties (existing values from the database)匹配属性(数据库中存在的值)
    PropertiesDatabase => {
        # See section "Properties", the same config can be used here.参阅“Properties”部分,那里的配置完全适用于此处。
        # ...
    }

    # reset possible options (white list)重置可用的选项(白名单)
    Possible => {
        # possible ticket options (white list)可用的选项(白名单)
        Ticket => {
            Queue => ['Hotline', 'Coordination'],
            State => ['some state'],
            Priority => ['5 very high'],
            DynamicField_Field1  => ['some value'],
            DynamicField_MyField => ['some value'],
            # ...
            NewOwner => ['some owner'],
            OldOwner => ['some owner'],
            # ...
        },

        # Limit the number of possible ActivityDialogs the Agent/Customer
        #   can use in a process ticket.
        #限制服务人员/客户在一个流程工单中可用的活动对话框数量
        ActivityDialog => ['AD1', 'AD3'],

        # Limit the number of possible Processes that can be started限制能启动的可用流程数量
        Process => ['Process-9c378d7cc59f0fce4cee7bb9995ee3eb', 'Process-12345678901234567890123456789012'],

        # possible action options (white list)可用的操作选项(白名单)
        Action => [
            'AgentTicketBounce',
            'AgentTicketPhone'.      # only used to show/hide the Split action
            'AgentLinkObject',       # only used to show/hide the Link action
            # ...
        ],
    },
    # add options (white list)添加选项(白名单)
    PossibleAdd => {
        # See section "Possible"参阅“Possible”部分
        # ...
    },
    # remove options (black list)移除选项(黑名单)
    PossibleNot => {
        # See section "Possible"参阅“Possible”部分
        # ...
    },
};
                


注意

匹配ACL时,如果传递了CustomerUserID参数,ACL机制会使用提供的CustomerUserID来比较的ACL定义,以便收集客户用户的详细信息来填充客户用户哈希表,在‘Properties’匹配时还会覆盖工单哈希表中的客户信息。另一方面,在‘PropertiesDatabase’匹配时也会计算,但是用工单客户为依据来收集信息数据。

注意:在客户界面,始终会传递当前登录的客户用户的CustomerUserID。

要知道在工单搜索屏幕(AgentTicketSearch和CustomerTicketSearch)唯一受ACL影响的就是动态字段。这意味着在工单搜索屏幕你不能限制其它任何属性比如工单类型、状态、队列等等。

从OTRS 4开始,‘操作’参数不再是一个哈希表,而是一个数组引用,并能使用任何修改器用于‘修改’部分。