diff --git a/README.md b/README.md index f156d2f521..77cf69eac9 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ will keep our community secure. If you happen to come across a security issue we you to disclose it to us privately to allow our users and community enough time to upgrade. Security issues will always take precedence over anything else in the pipeline. +For more information on how to disclosure a security vulnerability, [please see this page](docs/security/README.md). + ## License OpenProject is licensed under the terms of the GNU General Public License version 3. diff --git a/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass b/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass index 01c0345180..e7e84d1a14 100644 --- a/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass +++ b/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass @@ -5,8 +5,9 @@ float: left z-index: 0 - // Fallback color - background: #555 + .timeline-element--bg + width: 100% + height: 100% &:hover:not(.-clamp-style) .leftHandle, .rightHandle diff --git a/app/assets/stylesheets/content/work_packages/timelines/elements/_labels.sass b/app/assets/stylesheets/content/work_packages/timelines/elements/_labels.sass index 592b6b93d6..ec54e611fe 100644 --- a/app/assets/stylesheets/content/work_packages/timelines/elements/_labels.sass +++ b/app/assets/stylesheets/content/work_packages/timelines/elements/_labels.sass @@ -22,6 +22,7 @@ // Position container left of bar position: absolute left: 0px + top: 0px // Then translate by its own width + some margin transform: translateX(calc(-100% - 10px)) font-size: 12px diff --git a/app/services/add_attachment_service.rb b/app/services/add_attachment_service.rb index 04413ef35c..bdcef50bd5 100644 --- a/app/services/add_attachment_service.rb +++ b/app/services/add_attachment_service.rb @@ -55,16 +55,18 @@ class AddAttachmentService ActiveRecord::Base.transaction do attachment.save! - if container.respond_to? :add_journal - # reload to get the newly added attachment - container.attachments.reload - container.add_journal author - # We allow invalid containers to be saved as - # adding the attachments does not change the validity of the container - # but without that leeway, the user needs to fix the container before - # the attachment can be added. - container.save!(validate: false) - end + add_journal if container.respond_to? :add_journal end end + + def add_journal + # reload to get the newly added attachment + container.attachments.reload + container.add_journal author + # We allow invalid containers to be saved as + # adding the attachments does not change the validity of the container + # but without that leeway, the user needs to fix the container before + # the attachment can be added. + container.save!(validate: false) + end end diff --git a/db/migrate/20180510184732_rename_planning_elemnt_type_colors_to_colors.rb b/db/migrate/20180510184732_rename_planning_elemnt_type_colors_to_colors.rb index c6109b6ffc..f6a63b21d9 100644 --- a/db/migrate/20180510184732_rename_planning_elemnt_type_colors_to_colors.rb +++ b/db/migrate/20180510184732_rename_planning_elemnt_type_colors_to_colors.rb @@ -6,9 +6,13 @@ class RenamePlanningElemntTypeColorsToColors < ActiveRecord::Migration[5.1] rename_index :planning_element_type_colors, :timelines_colors_pkey, :planning_element_type_colors_pkey end - if ActiveRecord::Base.connection.execute("SELECT 1 as value FROM pg_class c WHERE c.relkind = 'S' and c.relname = 'planning_element_type_colors_id_seq'").to_a.present? - puts "Renaming id_seq to pkey which seems to be required by rename_table" - rename_index :planning_element_type_colors, :planning_element_type_colors_id_seq, :planning_element_type_colors_pkey + if ActiveRecord::Base.connection.execute("SELECT 1 as value FROM pg_class c WHERE c.relkind = 'S' and c.relname = 'planning_element_type_colors_id_seq'").to_a.present? || + begin + puts "Renaming id_seq to pkey which seems to be required by rename_table" + rename_index :planning_element_type_colors, :planning_element_type_colors_id_seq, :planning_element_type_colors_pkey + rescue => e + raise e unless e.message.match? /planning_element_type_colors_pkey.+?already exists/ + end end rename_table :planning_element_type_colors, :colors diff --git a/docker/mysql-to-postgres/bin/migrate-mysql-to-postgres b/docker/mysql-to-postgres/bin/migrate-mysql-to-postgres index a7b0fcafcb..67fa73367d 100755 --- a/docker/mysql-to-postgres/bin/migrate-mysql-to-postgres +++ b/docker/mysql-to-postgres/bin/migrate-mysql-to-postgres @@ -18,7 +18,7 @@ if db_url.scheme.start_with?("mysql") exit 0 # MySQL still supported until 9.x - with 10.0 we must make this an error (exit 1) end -if db_url.scheme.start_with?("postgresql") && mysql_url.nil? +if db_url.scheme.start_with?("postgres") && mysql_url.nil? # nothing to do exit 0 end @@ -108,7 +108,7 @@ puts "Importing database ..." mysql_url.query = nil mysql_url.scheme = "mysql" -_, pgloader_status = run "pgloader-ccl --verbose #{mysql_url} #{db_url}", record_output: false +_, pgloader_status = run "pgloader-ccl --with \"preserve index names\" --verbose #{mysql_url} #{db_url}", record_output: false if pgloader_status != 0 puts "\nFailed to import MySQL database into Postgres. See above." diff --git a/docs/operations/migrating/docker/postgresql-migration.md b/docs/operations/migrating/docker/postgresql-migration.md new file mode 100644 index 0000000000..2ff9a6d43e --- /dev/null +++ b/docs/operations/migrating/docker/postgresql-migration.md @@ -0,0 +1,111 @@ +# Migrating your Docker OpenProject database to PostgreSQL + +This guide will migrate your docker-based MySQL installation to a PostgreSQL installation using [pgloader](https://github.com/dimitri/pgloader). + +## Backing up + +Before beginning the migration, please ensure you have created a backup of your current installation. Please follow our [backup and restore documentation](https://www.openproject.org/operations/backup/backup-guide-docker-installation/) for Docker-based installations. + + + +## Built-in migration script + +The Dockerfile comes with a built-in PostgreSQL migration script that will auto-run and inform you what to do. + + + +### Set up a PostgreSQL database + +Depending on your usage, you may want to set up an external PostgreSQL database to provide the container with connection details just like you did for MySQL. + +In any case, you may also use the internally configured PostgreSQL instance of the docker container by using the DATABASE_URL ` postgres://openproject:openproject@127.0.0.1/openproject` + + + +**Installing a PostgreSQL database outside docker** + +If you want to set up a PostgreSQL installation database outside the container and not use the built-in database, please set up a PostgreSQL database now. These are generic apt-based installation steps, please adapt them appropriately for your distribution. + +OpenProject requires at least PostgreSQL 9.5 installed. Please check if your distributed package is too old. + +```bash +[root@host] apt-get install postgresql postgresql-contrib libpq-dev +``` + +Once installed, switch to the PostgreSQL system user. + +```bash +[root@host] su - postgres +``` + +Then, as the PostgreSQL user, create the system user for OpenProject. This will prompt you for a password. We are going to assume in the following guide that password were 'openproject'. Of course, please choose a strong password and replace the values in the following guide with it! + +```bash +[postgres@host] createuser -W openproject +``` + +Next, create the database owned by the new user + +```bash +[postgres@host] createdb -O openproject openproject +``` + +Lastly, exit the system user + +```bash +[postgres@host] exit +# You will be root again now. +``` + + + +### Setting environment variables + +To run the migration part of the image, you will have to provide two environment files: + + + +### The MYSQL_DATABASE_URL + +Note down or copy the current MySQL `DATABASE_URL` + +```bash +# Will look something something of the kind +# mysql2://user:password@localhost:3306/dbname + +# Pass into the container but replace mysql2 with mysql! +MYSQL_DATABSAE_URL="mysql://user:password@localhost:3306/dbname" +``` + + + +**Please note:** Ensure that the URL starts with `mysql://` , not with ` mysql2://` ! + + + +### The PostgreSQL DATABASE_URL + +Pass in `DATABASE_URL` pointing to your new PostgreSQL database. This is either the default `postgres://openproject:openproject@127.0.0.1/openproject` or if you set up a PostgreSQL installation above, use credentials for your installation you set up above. + +```bash +POSTGRES_DATABASE_URL="postgresql://:@/" +``` + + + +### Running the migration + +To run the migration script within the container, now simply run the following command, replacing the content of the environment variables with your actual values. + + + +```bash +docker run \ + -it openproject/community:latest + -e MYSQL_DATABASE_URL="mysql://user:password@localhost:3306/dbname" \ + -e DATABASE_URL="postgresql://openproject:@localhost:5432/openproject" +``` + + + +This will perform all necessary steps to perform the migration. Afterwards, simply remove the `MYSQL_DATABASE_URL`environment variable again and start your container as usual. \ No newline at end of file diff --git a/docs/operations/migrating/manual/postgresql-migration.md b/docs/operations/migrating/manual/postgresql-migration.md new file mode 100644 index 0000000000..b37a151cea --- /dev/null +++ b/docs/operations/migrating/manual/postgresql-migration.md @@ -0,0 +1,188 @@ +# Migrating your manual-installation OpenProject database to PostgreSQL + +This guide will migrate your MySQL installation on a manual installation to a PostgreSQL installation using [pgloader](https://github.com/dimitri/pgloader). + +## Backing up + +Before beginning the migration, please ensure you have created a backup of your current installation. Please follow our [backup and restore documentation](https://www.openproject.org/operations/backup/backup-guide-manual-installation/) for Docker-based installations. + + + +## Set up a PostgreSQL database + +Please first set up a PostgreSQL database. These are generic apt-based installation steps, please adapt them appropriately for your distribution. + +OpenProject requires at least PostgreSQL 9.5 installed. Please check if your distributed package is too old. + +```bash +[root@host] apt-get install postgresql postgresql-contrib libpq-dev +``` + +Once installed, switch to the PostgreSQL system user. + +```bash +[root@host] su - postgres +``` + +Then, as the PostgreSQL user, create the system user for OpenProject. This will prompt you for a password. We are going to assume in the following guide that password were 'openproject'. Of course, please choose a strong password and replace the values in the following guide with it! + +```bash +[postgres@host] createuser -W openproject +``` + +Next, create the database owned by the new user + +```bash +[postgres@host] createdb -O openproject openproject +``` + +Lastly, exit the system user + +```bash +[postgres@host] exit +# You will be root again now. +``` + + + +## The MYSQL_DATABASE_URL + +Note down or copy the current MySQL `DATABASE_URL`. The following command exports it to the curent shell as `MYSQL_DATABASE_URL`: + +```bash +# Will look something something of the kind +# mysql2://user:password@localhost:3306/dbname + +# Pass into the container but replace mysql2 with mysql! +export MYSQL_DATABSAE_URL="mysql://user:password@localhost:3306/dbname" +``` + + + +**Please note:** Ensure that the URL starts with `mysql://` , not with ` mysql2://` ! + + + +## The PostgreSQL DATABASE_URL + +Pass in `DATABASE_URL` pointing to your new PostgreSQL database. Fill the template below with the password you entered above. + +```bash +export POSTGRES_DATABASE_URL="postgresql://openproject:@localhost/openproject +``` + + + + + +## Running the migration via Docker + +OpenProject provides a simple conversion script that you can run as a single command via Docker. + +To run the migration script within the container, simply run the following command, replacing the content of the environment variables with your actual values. + + + +```bash +docker run \ + -it openproject/community:latest + -e MYSQL_DATABASE_URL=$MYSQL_DATABASE_URL \ + -e DATABASE_URL=$POSTGRES_DATABASE_URL +``` + + + +This will perform all necessary steps to perform the migration. Afterwards, simply remove the `MYSQL_DATABASE_URL`environment variable again and start your container as usual. + + + +## Running the migration without Docker + +### Installation of pgloader + + + +#### Apt Systems + +For systems with APT package managers (Debian, Ubuntu), you should already have `pgloader` available and can install as root with with: + +``` +[root@host] apt-get install pgloader +``` + + + +[For other installations, please see the project page itself for steps on installing with Docker or from source](https://github.com/dimitri/pgloader#install). + + + +After installation, check that pgloader is in your path and accessible: + + + +``` +[root@host] pgloader --version + +# Should output something of the kind +pgloader version "3.5.2" +compiled with SBCL 1.4.5.debian +``` + + + +### Performing the migration + +You are now ready to use `pgloader`. You simply point it the old and new database URL while specifying the option +`--with "preserve index names"` which ensures that index names are kept identical. + +```bash +pgloader --verbose --with "preserve index names" $MYSQL_DATABASE_URL $POSTGRES_DATABASE_URL +``` + +This might take a while depending on current installation size. + +### Index attachments for fulltext search + +One of the benefits of using PostgreSQL over MySql is the support for fulltext search on attachments. The fulltext search feature relies on the existence of two additional columns for attachments that need to be added now ff the migration to PostgreSql is done for an OpenProject >= **8.0**. If the OpenProject version is below **8.0** the next two commands can be skipped. + +In order to add the necessary columns to the database, run + +```bash +openproject run rails db:migrate:redo VERSION=20180122135443 +``` + +After the columns have been added, the index has to be created for already uploaded attachments + +```bash +openproject run rails attachments:extract_fulltext_where_missing +``` + +If a large set of attachments already exists, executing the command might take a while. + + + +### Indexes on relations table + +You will also need to rebuild the index on the relations table. Simply run the following command +to re-run the migration. + +```bash +openproject run rails db:migrate:redo VERSION=20180105130053 +``` + + + +## Optional: Uninstall MySQL + +If you installed MySQL only for the installation of OpenProject, evaluate whether you want to remove MySQL server. + +You can check the output of `dpkg - l | grep mysql` to check for packages removable. Only keep `libmysqlclient-dev` for Ruby dependencies on the mysql adapter. + + + +The following is an exemplary removal of an installed version MySQL 5.7. + +``` +[root@host] apt-get remove mysql-server +``` + diff --git a/docs/security/README.md b/docs/security/README.md new file mode 100644 index 0000000000..00e016dc8e --- /dev/null +++ b/docs/security/README.md @@ -0,0 +1,47 @@ +## Statement on Security + +At its core, OpenProject is an open-source software that is [developed and published on GitHub](https://github.com/opf/openproject). Every change to the OpenProject code base ends up in an open repository accessible to everyone. This results in a transparent software where every commit can be traced back to the contributor. + +Automated tests and manual code reviews ensure that these contributions are safe for the entire community of OpenProject. These tests encompass the correctness of security and access control features. We have ongoing collaborations with security professionals from to test the OpenProject code base for security exploits. + + + +### Security announcements mailing list + +We provide a mailing list for security advisories on OpenProject at . Please register there to get immediate notifications as we publish them. + +Any security related information will also be published on our blog and website at https://www.openproject.com + + + +### Reporting a vulnerability + +We take all facets of security seriously at OpenProject. If you want to report a security concerns, have remarks, or contributions regarding security at OpenProject, please reach out to us at [security@openproject.com](mailto:security@openproject.com). + +If you can, please send us a PGP-encrypted email using the following key: + +- Key ID: [0x7D669C6D47533958](https://pgp.mit.edu/pks/lookup?op=get&search=0x7D669C6D47533958) , +- Fingerprint BDCF E01E DE84 EA19 9AE1 72CE 7D66 9C6D 4753 3958 +- You may also find the key [attached in our OpenProject repository.](https://github.com/opf/openproject/blob/dev/docs/security/security-at-openproject.com.asc) + +Please include a description on how to reproduce the issue if possible. Our security team will get your email and will attempt to reproduce and fix the issue as soon as possible. + + + +## OpenProject Security features + +### Authentication. + +OpenProject administrators can enforce [authentication mechanisms and password rules]() to ensure users choose secure passwords according to current industry standards. Passwords stored by OpenProject are securely stored using salted bcrypt. Alternatively, external authentication providers and protocols (such as LDAP, SAML) can be enforced to avoid using and exposing passwords within OpenProject. + +### Two-step user registration + +In compliance with common requirements in works committees, ensure that new users added by project responsibles are confirmed by a superior before allowing the user to enter the system for the first time. + +### User management and access control. + +Administrators are provided with [fine-grained role-based access control mechanisms]() to ensure that users are only seeing and accessing the data they are allowed to on an individual project level. + +### Two-Factor authentication. (Cloud or Enterprise Edition) + +Secure your authentication mechanisms with a second factor by TOTP standard (or SMS, depending on your instance) to be entered by users upon logging in. [More information](). \ No newline at end of file diff --git a/docs/security/security-at-openproject.com.asc b/docs/security/security-at-openproject.com.asc new file mode 100644 index 0000000000..1a97a80679 --- /dev/null +++ b/docs/security/security-at-openproject.com.asc @@ -0,0 +1,102 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: User-ID: OpenProject Security +Comment: Fingerprint: BDCFE01EDE84EA199AE172CE7D669C6D47533958 + +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 +8K1kfQ4x8CiE2edqerbpajtKTiix +=WLl/ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/frontend/src/app/components/wp-card-view/wp-card-view.component.html b/frontend/src/app/components/wp-card-view/wp-card-view.component.html index bd0d141686..de1206fd5a 100644 --- a/frontend/src/app/components/wp-card-view/wp-card-view.component.html +++ b/frontend/src/app/components/wp-card-view/wp-card-view.component.html @@ -49,6 +49,11 @@ + + #{{wp.id}} +