[[schemaChangev800]]
= Changes to Schema in v8.0.0
:author: Andrzej Wójcik & Daniel Wisnewski
:version: v1.0 October 2017

For version 8.0.0 of Tigase XMPP Server, we decided to improve authentication and security that was provided. In order to do this, implementation of repository and database schemas needed to be changed to achieve this goal.
This document, as well one in the HTTP API, will describe the changes to the schemas in this new version.

== Reasons
Before version 8.0.0, user passwords were stored in plaintext in `user_pw` database field within `tig_users` table, but in plaintext.
It was possible to enable storage of the MD5 hash of the password instead, however this limited authentication mechanism SASL PLAIN only.
However an MD5 hash of a password is not really a secure method as it is possible to revert this mechanism using rainbow tables.

Therefore, we decided to change this and store only encrypted versions of a password in PBKDF2 form which can be easily used for `SCRAM-SHA-1` authentication mechanism or `SCRAM-SHA-256`.
SASL PLAIN mechanism can also used these encrypted passwords. The storage of encrypted passwords is now enabled *by default* in v8.0.0 of Tigase.

== Summary of changes

=== Added support for storage of encrypted password
Passwords are no longer stored in plaintext on any database.

=== Using same salt for any subsequent authentications
This allows clients to reuse calculated credentials and keep them instead of storing plaintext passwords.

=== Disabled usage of stored procedure for authentication
In previous versions, Tigase used stored procedures `TigUserLoginPlainPw` and `TigUserLogin` for SASL PLAIN authentication.
From version 8.0.0, those procedures are no longer used, but they are updated to use passwords stored in `tig_user_credentials` table.


It is still possible to use this procedures for authentication, but to do that you need add:
[source,tdsl]
----
'user-login-query' = '{ call TigUserLoginPlainPw(?, ?) }'
----
to configuration block of *every* authentication repository.

To enable this for default repository, the `authRepository` configuration block will look like this:
[source,tdsl]
----
authRepository () {
    default () {
        'user-login-query' = '{ call TigUserLoginPlainPw(?, ?) }'
    }
}
----

=== Deprecated API
Some methods of `AuthRepository` API were deprecated and should not be used.
Most of them were used for authentication using stored procedures, retrieval of password in plaintext or for password change.

For most of these methods, new versions based on `tig_user_credentials` table and user credentials storage are provided where possible.

=== Deprecated storage procedures
Stored procedures for authentication and password manipulation were updated to a new form, so that will be possible to use them by older versions of Tigase XMPP Server during rolling updates of a cluster.
However, these procedures will not be used any more and will be depreciated and removed in future versions of Tigase XMPP Server.

=== Usage of MD5 hashes of passwords
If you have changed `password-encoding` database property in previous versions of Tigase XMPP Server, then you will need to modify your configuration to keep it working.
If you wish only to allow access using old passwords and to store changed passwords in the new form, then you need to enable credentials decoder for the correct authentication repository.
In this example we will provided changes required for `MD5-PASSWORD` value of `password-encoding` database property.
If you have used a different one, then just replace `MD5-PASSWORD` with `MD5-USERNAME-PASSWORD` or `MD5-USERID-PASSWORD`.

.Usage of MD5 decoder
[source,tdsl]
----
authRepository () {
    default () {
        credentialDecoders () {
            'MD5-PASSWORD' () {}
        }
    }
}
----

If you wish to store passwords in MD5 form then use following entries in your configuration file:

.Usage of MD5 encoder
[source,tdsl]
----
authRepository () {
    default () {
        credentialEncoders () {
            'MD5-PASSWORD' () {}
        }
    }
}
----

=== Enabling and disabling credentials encoders/decoders
You may enable which encoders and decoders used on your installation.
By enabling encoders/decoders you are deciding in what form the password is stored in the database.
Those changes may impact which SASL mechanisms may be allowed to use on your installation.

.Enabling PLAIN decoder
[source,tdsl]
----
authRepository () {
    default () {
        credentialDecoders () {
            'PLAIN' () {}
        }
    }
}
----

.Disabling SCRAM-SHA-1 encoder
[source,tdsl]
----
authRepository () {
    default () {
        credentialEncoders () {
            'SCRAM-SHA-1' (active: false) {}
            'SCRAM-SHA-256' (active: false) {}
        }
    }
}
----

WARNING: It is strongly recommended not to disable encoders if you have enabled decoder of the same type as it may lead to the authentication issues, if client tries to use a mechanism which that is not available.


=== Schema changes
This change resulted in a creation of the new table `tig_user_credentials` with following fields:

uid:: id of a user row in `tig_users`.
username:: username used for authentication (if `authzid` is not provided or `authzid` localpart is equal to `authcid` then row with `default` value will be used).
mechanism:: name of mechanism for which this credentials will be used, ie. `SCRAM-SHA-1` or `PLAIN`.
value:: serialized value required for mechanism to confirm that credentials match.

WARNING: During execution of `upgrade-schema` task, passwords will be removed from `tig_users` table from `user_pw` field and moved to `tig_user_credentials` table.


=== Added password reset mechanism
As a part of Tigase HTTP API component and Tigase Extras, we developed a mechanism which allows user to reset their password.
To use this mechanism HTTP API component and its REST module *must* to be enabled on Tigase XMPP Server installation.

NOTE: Additionally this mechanism need to be enabled in the configuration file. For more information about configuration of this mechanism please check Tigase xref:hTTPAPI[HTTP API component] documentation.

Assuming that HTTP API component is configured to run on port 8080 _(default)_, then after accessing address http://localhost:8080/rest/user/resetPassword in the web browser it will present a web form.
By filling and submitting this form, the user will initiate a password reset process.
During this process, Tigase XMPP Server will send an email to the user's email address (provided during registration) with a link to the password change form.


== Upgrading from v7.1.x
When upgrading from previous versions of Tigase, it is recommended that you first backup the database. Refer to the documentation of your database software to find out how to export a copy.
Once the backup is made, it will be time to run the schema upgrade. Be sure that your schema is up to date, and should be v7.1.0 Schema.

To upgrade, use the new `upgrade-schema` task of SchemaManager:

* In linux
+
[source,bash]
-----
./scripts/tigase.sh install-schema etc/tigase.conf
-----
+
* In Windows
+
[source,bash]
-----
java -cp "jars/*" tigase.db.util.SchemaManager "install-schema"
-----

You will need to configure the following switches:

- `-T` Specifies Database Type +
  Possible values are: `mysql`, `derby`, `sqlserver`, `postgresql`, `mongodb`

- `-D` Specifies Databse Name +
  The explicit name of the database you wish to upgrade.

- `-H` Specifies Host address +
  By default, this is localhost, but may be set to IP address or FQDNS address.

- `-U` Specifies Username +
  This is the username that is authorized to make changes to the database defined in -D.

- `-P` Specifies Password +
  The password for username specified in -U.

- `-R` Password for Administrator or Root DB account.

- `-A` Password for Administrator or Root DB account.

- `-J` Jid of user authorized as admin user from Tigase.

- `-N` Password for user specified in -J.

- `-F` Points to the file that will perform the upgrade. +
  Will follow this form database/{dbname}-server-schema-8.0.0.sql
