blob: 5a5cc30471cdef949b86ffc1749517025fc52cd6 [file] [log] [blame]
[[section-concepts]]
== Cross-cutting Concepts
=== Role concept
The creation of a new statement response requires the collaboration of multiple editors from different company domains. They enhance the statement by adding domain specific information, comments that should support the final creation of the response document or verify the document for approval. The statement process is therefore divided up into multiple sequenced tasks each of which can be matched to one or more abstract user roles. A suitable role and rights concept must restrict general access to a previously defined group of editors as well as restricting the editing according to additional parameters like the current task and assigned user roles. This should be ensured by an adapted front-end visualization as well as a verification of the concrete edit type and parameters in the back-end service.
The authorization logic is therefore implemented in a multi-tier validation process.
To identify an access user, the external core module AuthNAuth is used. Each user of the Statement Public Affairs module is verified by a token generated by the AuthNAuth module. The assigned user roles managed by the AuthNAuth module can be used by the statement module to authorize the access interfaces.
The overall access to the user interface as well as the back-end api is authorized by a basic role SPA_ACCESS that has to be assigned to each user of the Statement Public Affairs module.
This role grants the user readable access to statement overview and details. Besides that, editing of statement details like attachments, comments or text-blocks is only allowed in certain statement process tasks and only granted to specific user roles. To prevent inconsistencies it shall be ensured, that only one user can edit a statement at the same time. This is ensured by a user to task assignment where only the currently assigned process task user is authorized to edit the statement.
With this in mind one can abstract the following basic rules:
* General read access is granted by the basic SPA_ACCESS role
* Editing access is only granted for the currently assigned user
* The concrete edit authorization is specific to the statement process task and the user roles
==== Roles
[cols="30%, 70%", options="header"]
|===
| Role | Description
| SPA_ACCESS | Basic role that provides module access
| SPA_ADMIN | Configures the statement module
| SPA_OIC | Official in charge who does the formal statement editing
| SPA_DIVISION_MEMBER | Member of a division who enhances the statement with domain specific information
| SPA_APPROVER | Approves finished statements or negative responses
| SPA_GUEST | Browses statements that are still in process or already finished
|===
==== Verification
As shown in the authorization process diagram the verification is a multi-tier process.
image::authorization-process.svg[]
The first tier is the only granted based on the SPA_ACCESS user role that every statement module user shares.
The next tiers differ in the concrete access types. Access types can be grouped into process task specific access and general access. General access is only verified by the user roles. Examples for these access types are reading statement details or starting a new statement process. The other access types are specified for each process task. To process a task, the user has to temporarily claim the task. This claim-user is matched with the access user. The last step of the task specific access authorization verifies the User Roles in combination with the task.
==== Backend
In the API back-end, the three layers are implemented as follows.
The verification of the SPA_ACCESS role is implemented as a general precondition to access an end-point. This reduces the attack surface of the service as only little code is executed before access is denied.
A central authorization service implements the other two verification layers. It has interfaces to verify the task specific access and the general access types and is requested in the beginning of each end-point logic.
The central authorization service is configured by an authorization matrix that sets the role and task specific access rights.
==== Frontend
The basic strategy for the front end is to only render specific views or user controls if the user is authorized to read or use them. User roles as well as the information on tasks are stored centrally in the web application. On a change, all views are updated with the new data and display or hide certain parts of it.
In the front end application, the first tier of access is verified right at the initialization when all roles for the user are loaded from the back end. If the user is not provided with general read access, only an error message is rendered. Otherwise, the user has access to the main views of the application.
Certain sub pages, e.g. the settings page for configuring the module, can only be accessed with a specific user role. If a user is not provided with all necessary roles, links to the sub pages are not rendered in the navigation bar. Route guards ensure that a user can not access restricted sub pages via an URL route and redirect to the main landing page in this case.
The second tier of access is verified if a user wants to view or edit a specific user task. For example, user controls to claim a task are only rendered if the task is not claimed by another user and if the user is actually allowed to do so by its assigned roles.
Details of a statement can only be edited on a specific sub page: the edit page. When accessing the edit page for a specific task, first the relevant task information is loaded (or updated) and different kind of views are presented to the user based on the task information and the user's roles.
While visiting the web application, roles can be revoked from the user. If so and if the user is trying to access now restricted areas of the web application, the user is logged out automatically. This essentially forces the user to revisit the website. It is also possible that the user's claim on a statement task is revoked. If so, all currently displayed views are updated accordingly to the new task information. For example, the edit page is updated and displays now a simple message instead of a form to edit the statement's details.
=== Text block concept
Based on the given general information regarding a statement, a textual response is formulated which is finally sent to the recipient. As the actual writing follows a standardized process, most parts of the text can be reused in various requests and only a small portion of it has to be adjusted to the specific situation, for example the contact person's name, the current date or simple free text which has to be defined by the user.
When creating the statement response draft or final version, the responsible editor shall be able to put together the response text by selecting multiple text blocks, sort them and enhance them with case specific details. In addition, text blocks can have interdependencies. They may require predecessors, just make sense in a specific order or exclude each other. A text block concept is required that allows the administration of reusable text blocks including interdependency rules, order restrictions and the ability to define placeholders that can be used to adapt a text block to a specific case. Before creating the final document text block restrictions like placeholders, order, etc. shall be verified to ensure a consistent document text.
==== Block administration
The administration of the text blocks shall support the following modifications:
* Create new and delete existing text block groups
* Create new and delete text blocks
* Modify existing text blocks
* Rearrange text blocks
* Set interdependencies between text blocks of the same group
* Set variable text block place holders in text blocks
The text block configuration is persisted in a single definition format that is versioned, so that it can be referenced in the creation process. This ensures that modifications of the text block definition do not affect statements that are already under development.
==== Text formatting
Text block content may be formatted. The following format types are supported:
* bold
* italic
* lists with bullet points
* newlines
They can be manually set using a markup language with the following rules:
[cols="20%,15%,65%", options="header"]
|===
| Type | Rule | Example
| *bold* | \*<text>* | That's a \*bold* text.
| _italic_ | \_<text>_ | That's a \_italic_ text.
| bullet points | * Bullet | * That's a list entry
|===
Newlines can be set inside the text block by using enter or using the special character \n manually.
==== Text place holder
There are three main types of text place holders:
* Free text can be of any textual form and may include formatted text or specific data from the statement’s general information like the title, dates and the contact person's name
* Freely fillable date fields
* Texts which can be chosen from a predefined list of options
They can be manually set according to the following rules:
[cols="20%,15%,65%", options="header"]
|===
| Type | Rule | Example
| free text | <f:name> | Here's some random text: <f:random>.
| date | <d:name> | Here's some date: <d:name>.
| statement info| <t:name> | Referencing your request with the due date of <t:dueDate>, ...
| select | <s:name> | Techspecs of the windmill: <s:ts_windmill>
|===
To be able to match statement info place holder variables with statement info data text response generators for a defined set of variables are implemented in the back-end.
The source for the common place holders is a configuration file that contains a single replacement string or a list of replacement entries with a short handle that can be represented as a selection in the front-end.
==== Persistence
===== Definition
The text block definition structure is as follows:
[source,json]
----
{
"groups": [
{
"name": "<string>",
"blocks": [
{
"id": "<string>",
"text": "In the urban area of <t:city> we are operator of the network division(s) <t:divisions>.",
"requires": [
{
"type": "<and|or|xor>",
"ids": ["<block-id>", ...]
}
],
"excludes": ["<block-id>",...]
}
]
}
]
}
----
To ensure that modifications of the text block definition do not affect statements under development certain rules are established:
* The definition has to be versioned
* The current definition version is assigned to a new statement before the first time a draft of the statement response is created
The definition is persisted in the database in JSON format.
===== Statement response
The persisted statement response holds the current compilation of text blocks. Therefore it includes a reference of the specific statement definition version.
The detailed structure is as follows:
[source,json]
----
{
"blocks": [
{
"type": "text",
"replacement": "That's a free text block."
},
{
"type": "block",
"textblockId": "1a",
"addNewline": true,
"placeholderValues": {
"f:freetext1": "free text",
"d:date1": "2020-06-30",
"s:select1": "<selectId>"
}
},
{
"type": "newline"
},
{
"type": "pagebreak"
}
]
}
----
==== Backend API
[cols="10%,60%,30%", options="header"]
|===
| Req | Uri | Description
| GET | /admin/text | Get current text block definition
| POST | /admin/text | Set new text block definition
| GET | /process/statements/{sId}/workflow/textarrangement | Get current text block compilation of statement
| POST | /process/statements/{sId}/task/{tId}/workflow/textarrangement | Set text block compilation of statement
|===
=== User notification via email
The process of collecting information to create a statement response is achieved by multiple statement editors contributing information from their knowledge domain. An efficient statement process requires a coordination of these different contributions via an email notification mechanism.
Contributors of a statement shall be informed about important process steps at the transitions to the next process user task. Examples for these transitions are the notification of all users with the role SPA_Approver when a new positive or negative statement response shall be cleared or to inform all contributors when a statement process is finished.
Therefore a notification component is required that is triggered when a process task is finished. If the current process task is configured for notification, all the contributors and configured ROLES shall be notified. The list of recipients consists of the contributors, all with ROLE official in charge, all approvers, or all users of the departments set in the statement workflow-data.
The email account used for the notification mechanism should be a no-reply or a support account and should not be the same as the one for the statement inbox email account to avoid troubling response email in the statement inbox.
The email text is configurable and contains the statement id, title for a simple evaluation by the recipient and a link to the details view of the specific statement.
The email itself is sent via a configured email account connected via SMTP and an encrypted SSL connection.
=== Statement email inbox
New statement processes can be initiated in two different ways. An official in charge can initiate a new statement that was received via mail manually or transfer a statement request from an email inbox semi-automatically into a new statement process.
Email is a communication type that does not include a proper sender identification. There's currently no identification method planned to ensure that spam e-mails can be filtered out reliably. As a consequence, new statement requests cannot automatically be transferred into new statement processes and need to be semi-automatically transferred by a statement official in charge.
The semi-automatic transfer is implemented as a separate view to initiate new statement processes. There is a list of current emails that have not been processed by another statement process member. To evaluate that a new email is a legitimate statement request, the content of the email such as the email text and the attachments should be accessible within that view. For security reasons, the email content will only be shown as plain text. HTML content will not be rendered. An email content typically consists of multiple parts including the email text as plain-text or HTML, a signature and attachment files. For the detail view in the INBOX, all content parts that are not attachments are concatenated and presented as plain-text. With that, the content can be read and security issues that can be caused by rendering HTML content can be prevented. When transferred, the content is added as an attachment to the new statement process.
Via the email communication protocol IMAP, the statement module can manage incoming mails of the statement mailbox. With that access one can list all new e-mails and process them by deleting unwanted e-mails, flag e-mails as read or unread and structure them by moving e-mails in a folder like structure. To manage the incoming statement request e-mails the statement specific mailbox folders are structured as follows:
[cols="30%,70%", options="header"]
|===
| Folder | Description
| INBOX | Inbox folder where all new e-mails are delivered to
| PROCESSED | Folder where e-mails are moved to when a new statement process is initiated based on that e-mail
| OTHER | Folder where e-mails are moved to that a statement official in charge selected as spam or for deletion
|===
With that an administrator is still able to access the mailbox with an email client with a reduced risk of interfering with the mechanism of the statement module to distinguish between new and already processed statement requests. Other mechanisms like flagging an email as READ can be set by accident when an administrator browses through the email folders with an email client. In case a statement official in charge deleted a legitimate statement request by accident it can still be found by an administrator within the OTHER folder and moved back to the INBOX folder with any email client. There it will show up again as a new request in the statement module view.
To ensure that no other will interfere with that mechanism, the email address used for the external statement process communication should only be used for that purpose.
When a new statement process is initiated, the request email is linked to the statement by the unique email MessageId that is part of the email header (RFC/3051). With that, it is possible to identify the request email afterwards and access the email text and attachments again later in the statement process when for instance an email-attachment was forgotten to be transferred to the statement process. Attachments of an e-mail themselves can be uniquely identified by their content sequence number and the file name.
=== Statement response dispatch
After the successful statement process the positive or negative response can be either delivered via mail or e-mail. The response message consists of a response letter and optional attachments. In case of a response via e-mail, the response mail consists of a plain-text response with the response letter attached as a PDF document. Additionally attachments can be selected that are sent together with the response e-mail.
The same e-mail address as the statement request inbox is used to deliver the response e-mail. Therefore the same e-mail address as the statement request inbox is used. In cases where the response cannot be delivered or no recipient e-mail address is available, the response letter PDF together with additional response attachments can be downloaded and sent via mail.
=== Statement response PDF
During the statement process all contributors help forming a statement response text that is compiled together into an official response letter. The persistence format of these contributions and the text compilation is specified in the concept section <<Text block concept,Text block concept>>. The form of the response letter is a single- or multi-paged PDF document according to the size of the response text. For the generation of the PDF document a template based solution was chosen.
==== PDF templates
To generate a response letter in form of a PDF document the following procedure is used.
The PDF documents are generated by using a letter paper template PDF and a definition of the position and size of text blocks that are placed on the letter paper. The content structure of a response letter is as follows:
image::pdf-concept.svg[]
As shown in the diagram above, the first page has a similar structure as a business letter. It contains of the three text blocks
address-block, infodata-block and content-block. The address-block shows the recipient address with values like company address and and recipient name that are part of the statement-info-data-set. The infodata-block contains predefined text as well as information from the statement-infodata-set.
The text-block compilation that is created by the statement contributors is then printed as left-aligned text in the content-block. If the content exceeds the size of the content block of a page, an additional page that uses a different letter paper template and contains only a content-block is added. The letter ends with a predefined closing and a signature part.
The template can be configured according to a specific letter format and consists of a two page PDF document and a configuration file with the text-block positions and text-block sizes. Page one of the template PDF is the first page. Page two is used for all following pages.
Each text- block is referenced as follows:
* type [address | info | content-p1 | content-p2]
* top-left (x,y) position in cm (float) from the top-left document corner
* width, height in cm (float)
* text lines that can contain statement placeholders
* fontsize
The closing has special configuration including the salutation and up to two signature fields. The position is relative to the current text position.
Configuration format:
[source,json]
----
{
"address": {
"x": 10.2,
"y": 4.2,
"width": 5.3,
"height": 10.3,
"fontsize" : 10
},
"info": {
"x": 10.2,
"y": 4.2,
"width": 5.3,
"height": 10.3
"text": ["each", "line", "as", "separate", "entry"],
"fontsize" : 8
},
"content-p1": {
"x": 10.2,
"y": 4.2,
"width": 5.3,
"height": 10.3,
"fontsize" : 10
},
"content-p2": {
"x": 10.2,
"y": 4.2,
"width": 5.3,
"height": 10.3,
"fontsize" : 10
},
"closing": {
"salutation": ["Sincerely yours", "another line"],
"signatures": [
{
"xrel":2.1,
"yrel":3.2,
"width": 5.1
"label" : ["First Lastname", "Second line"]
"fontsize" : 10
}, ...
]
}
}
----
==== PDF response text
The response content formulated during the statement process is stored as a set of text parts. For generating the response text a simple form of type-setting is used. Text that exceeds the configured with of a text-block is wrapped after the last token that fits the boundary. Text tokens are generated by cutting the text along the blanks. When a text part does not fit into the height of a content text-block a new page is generated and the whole text-block is then printed onto the new page.
As described in the section <<Text formatting,Text formatting>> the response text can contain bold and italic text as well as bullet point lists.
At the end, the response is closed with the configured closing.