> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superoffice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Database security

> Security considerations for the SuperOffice database, including the Sentry access-rights system.

If you have never programmed against the SuperOffice database before, see the [Getting started][1] section.

## Single database user

We used to have:

* application user = database user
* application password = database password.

No more! Now there is a single, common database user, separate from the application user concept. NetServer will log on using this (and now NetServer is always started first, by all applications). Other code (C++) will "inherit" the settings.

The database user/password is specified in the .config file. We will come up with a system for maintaining and distributing this information in a reasonable and safe manner. What you type into ServerSetup goes (via an MST transform) into the MSI client installer and *SuperOffice.config*.

<Note>
  The upgrade neither creates nor deletes any database users. The code to do so is completely disabled in SuperOffice v.7. Database users and their settings and rights are the responsibility of the customer.
</Note>

We do still create the groups SOADMIN and SOUSER. You can create new database users (by using the DB tools), and then assign them to one of these groups; SOADMIN recommended!  That way they will get the correct rights. Or you can simply assign CRUD rights to all SuperOffice tables to a new database user, and that should be it.

The user is specified in SuperOffice/Data/Explicit in the config file.

For SuperOffice Web, this still also needs to be a System User (create via SoAdmin). This requirement will probably go away and be reduced to just a database user.

Do not use the "Trusted login" setting of ODBC sources, since it overrides the login and makes you dependent on having database users for all AD users.

## Sentry

What is sentry? As the name implies it acts as **the watchdog or traffic cop that keeps an eye on all the access to data in the SuperOffice database**.

Each object in NetServer has an associated sentry that is responsible for enforcing rules such as "private appointments are visible only to its owner". Sentry rules focus on ownership, group membership, and user-level access.

Sentry is a shared component used by all SuperOffice code to evaluate access rights. The Sentry objects answer questions regarding which tables and fields are accessible to a given type of operation, but do not themselves **enforce** these rights - this is up to the various client objects.

In SuperOffice the security is based on roles so all the user of SuperOffice belongs to a role. The different roles have different levels of rights to access the data in the database so Sentry is the mechanism that ensures that these levels get the proper data access. The levels of data access rights in SuperOffice are as follows.

* None
* Read
* Create
* Update
* Delete

Here *None* means that the user does not have any rights to the data, Read means that the user can read the data, Create means the user can create rows in a table, Update means the user can update the data and Delete means the user can delete the data. If a user has the right to Delete a data item that means that the user has the right to Read, Create and Update the data and if the user has the right to Update the user will have the rights to Create and Read as well like-wise the rights will be determined.

The role defines what rights he has to the data that he owns, data owned by other associates in his primary user group, and to associates of the other user groups he belongs to. It also defines what rights he has to data that belong to other associates outside his user groups and external users/anonymous users. All the users of the SO CRM application will have a role. The rights to each data item will be determined by these roles so that means there is a mechanism in place to protect access to data.

### Sentries, main tables, and sub-tables

The Sentry system is responsible for evaluating access rules. It consists of a common base class, and a subclass for each **main table** there is a Sentry for. The main tables at the time of writing are:

* contact
* person
* project
* appointment
* sale
* selection
* relation

Each Sentry, then, implements the rules that apply to its main table. However, a Sentry typically also handles one or more **sub-tables**, which contain data subordinate to the main table. Rights to the sub-table records are generally derived from rights to the main table record. The sub-tables are:

| Main table  | Sub-tables                                                                  |
| ----------- | --------------------------------------------------------------------------- |
| contact     | Address, Phone, Email, Url, Text, ContactInterest, UdContSmall, UdContLarge |
| person      | Address, Phone, Email, Url, Text, PersonInterest, UdPersSmall, UdPersLarge  |
| project     | Text, Url, ProjectMember, UdProjSmall, UdProjLarge                          |
| appointment | Document, Text                                                              |
| sale        | Text, UdSaleSmall, UdSaleLarge                                              |
| selection   | SelectionMember                                                             |
| relation    |                                                                             |

Rights overrides may be applied to any table or field that is a main table or a sub-table of a main table.

### Sentry in services

In the NetServer service layer, the sentry information is provided in 2 properties:

* [FieldProperties](#fieldproperties)
* [TableRight](#tableright)

#### FieldProperties

The `FieldProperties` is the mechanism that is provided by NetServer to **check the individual field access rights** of the logged-in user. All the entities of the service layer will have this property.

A typical use of this property is to check the data rights of the user before making a change or before reading a value. We can use this property for many other purposes like to check the data rights and disable a certain button or a read-only field.

##### FieldRight

We can use several properties provided by the `FieldRight` property (of a field) to check for rights. The most commonly used ones are listed below.

| Property      | Description                                                                                      |
| ------------- | ------------------------------------------------------------------------------------------------ |
| IsActive      | whether this field is active for the logged-in user: Does the user have the right to this field? |
| HasAll        | whether the user has all the rights to the field                                                 |
| HasNone       | returns true is the user does have any rights to the field                                       |
| IsMandatory   | if this field is mandatory in the database                                                       |
| IsUiMandatory | if this field is mandatory in the UI                                                             |
| Mask          | whether a certain field right is available for the user                                          |
| Reason        | lets us retrieve the reason why a given user can not access the field                            |

The `Reason` property will have a reason if the user does not have the full permission (Read, Create, Update, and Delete) however if the user has full permission the reason property will be blank.

#### TableRight

The `TableRight` property focuses on the table as a whole. It has mechanisms to determine whether the logged-in user has the rights to the table.

A typical use of this property is as follows: imagine you have a full form of fields that are of contact information. If a particular user logging in does not have the right to change data, you can make all the fields disabled.

It's easier to check the rights of the table than checking each field if you are trying to restrict updates to an entire table since it is easy checking the right of the table than checking each field by field.

<Note>
  If you let the user do some operation that the user does not have proper rights to, NetServer will throw errors so it is always good to check for data rights before we let a user do some operation.
</Note>

`TableRight` exposes its value as a set of flags. We recommend creating an enum such as the one below (C#, adapt to your language of choice):

```csharp theme={null}
[Flags]
public enum ETableRight
{
  None = 0,
  Select = 1,
  Update = 2,
  Insert = 4,
  Delete = 8,
  Filtering = 16,
  RestrictedUpdate = 32,
  Uninitialized = 128,
};
```

[1]: ./getting-started/index


## Related topics

- [Creating the CRM7 user](/en/onsite/install/database/create-oracle-db#creating-the-crm7-user.md)
