This application enables integration between Nextcloud and open-source project management software OpenProject.
On the Nextcloud end, it allows users to:
- Link files and folders with work packages in OpenProject
- Find all work packages linked to a file or a folder
- View OpenProject notifications via the dashboard
- Search for work packages using Nextcloud's search bar
On the OpenProject end, users are able to:
- View all Nextcloud files and folders linked to a work package
- Download linked files or open them in Nextcloud to edit them
Please report issues and bugs here: https://community.openproject.org/projects/nextcloud-integration/work_packages
- For documentation on how to use the integration once it is set up, refer to Using the Nextcloud integration.
- For documentation on how to set up the integration as an administrator, refer to Nextcloud integration setup.
Note: Setting up the integration can only be done by admin user but not a normal user
We have a single API endpoint (/setup) available to set up, update and reset the integration.
To set up or update the integration following data needs to be provided:
- openproject_instance_url
- openproject_client_id
- openproject_client_id
- default_enable_navigation
- default_enable_unified_search
- setup_project_folder
- setup_app_password
Note:
- We can set up the integration with or without
project folders- To set up the integration without
project folderswe need to set datasetup_project_folder=falseandsetup_app_password=false- To set up the integration with
project folderswe need to set datasetup_project_folder=trueandsetup_app_password=true, this will create a new user, group, and group folder named OpenProject if the system doesn't already have one or more of these present. Also, an application password will be provided for the userOpenProject- Once the
project folderhas already been set up, the createdOpenProjectuser and group cannot be disabled or removed.- If there is any error related to
OpenProjectuser, group, group folders when setting up the whole integration or if the admin user wants to remove those entities then this troubleshooting guide can be followed up on how to resolve it.
-
Set up the whole integration with a [POST] request
We must provide all of the above data for this request.
Example curl request to set up whole integration with
project folderscurl -XPOST -u<nextcloud_admin_username>:<nextcloud_admin_password> http://<nextcloud_host>/index.php/apps/integration_openproject/setup \ -d '{"values":{"openproject_instance_url":"<openproject_instance_url>","openproject_client_id":"<openproject_client_id>","openproject_client_secret":"<openproject_client_secret>","default_enable_navigation":false,"default_enable_unified_search":false,"setup_project_folder":true, "setup_app_password":true}}' \ -H 'Content-Type: application/json' -v
The response from the above curl request
{ "nextcloud_oauth_client_name": "<openproject-client>", "openproject_redirect_uri": "http://<openproject_instance_url>/oauth_clients/<nextcloud_client_id>/callback", "nextcloud_client_id": "<nextcloud_client_id>", "nextcloud_client_secret": "<nextcloud_client_secret>", "openproject_user_app_password": "<openproject_user_app_password>", "openproject_revocation_status": "<openproject_revocation_status>" } -
Update the integration with a [PATCH] request
One or more of the above data needs to be sent to this endpoint
Example curl request to update only
openproject_client_idandopenproject_client_secretcurl -XPATCH -u<nextcloud_admin_username>:<nextcloud_admin_password> http://<nextcloud_host>/index.php/apps/integration_openproject/setup \ -d '{"values":{"openproject_client_id":"<openproject_client_id>","openproject_client_secret":"<openproject_client_secret>"}}' \ -H 'Content-Type: application/json' -v
The response from the above curl request
{ "nextcloud_oauth_client_name": "<openproject-client>", "openproject_redirect_uri": "http://<openproject_instance_url>/oauth_clients/<nextcloud_client_id>/callback", "nextcloud_client_id": "<nextcloud_client_id>", "nextcloud_client_secret": "<nextcloud_client_secret>", "openproject_revocation_status": "<openproject_revocation_status>" }Note: If the integration is done with
project foldersthen we can update/change the oldOpenProjectuser's application password by settingset_app_password=true. Then we get new application password as"openproject_user_app_password: <openproject_user_app_password>"in the above JSON response. -
Resetting the whole integration with a [DELETE] request
Example curl request to reset whole integration
curl -XDELETE -u<nextcloud_admin_username>:<nextcloud_admin_password> http://<nextcloud_host>/index.php/apps/integration_openproject/setup -v
The response from the above curl request
{ "status": true, "openproject_revocation_status": "<openproject_revocation_status>" }
Note: In the response
openproject_revocation_statusis included only after a successful connection
integration_setup.sh sets up the whole integration with just one command.
Prerequisites needed for using the shell script.
- "OpenProject" is set up and running
- "Nextcloud" is set up and running
- The "OpenProject Integration" app is installed and enabled in Nextcloud.
- The credentials of the OpenProject global user are known
- In "Nextcloud" we already have set up an admin with credentials.
Once all the above pre-conditions are met we can run the shell script to integrate with the following command.
Note:
- We can set the whole integration with or without
project foldersusing this script with an environment variableSETUP_PROJECT_FOLDERSETUP_PROJECT_FOLDER=truewill set the integration withproject foldersand vice-versa
Also, the following bash command has an environment variable OPENPROJECT_STORAGE_NAME which will be the storage name to store the oauth information in Open Project required for integration.
Below is an example of a command to run the script to set up the integration with project folders
SETUP_PROJECT_FOLDER=true \
NEXTCLOUD_HOST=<nextcloud_host_url> \
OPENPROJECT_HOST=<openproject_host_url> \
OP_ADMIN_USERNAME=<openproject_global_admin_uername> OP_ADMIN_PASSWORD=<openproject_global_admin_password> \
NC_ADMIN_USERNAME=<nextcloud_admin_username> NC_ADMIN_PASSWORD=<nextcloud_admin_password> \
OPENPROJECT_STORAGE_NAME=<files_storage_name> \
bash integration_setup.shNote: these credentials are only used by the script to do the setup. They are not stored/remembered.
There's an end-point direct-upload available which can be used for direct-upload. There's two steps to direct upload. First we need to get the token. Then use the token in the direct upload request.
-
Preparation for direct upload: Send the
POSTrequest todirect-upload-tokenend-point with datafolder_idof the destination folder.curl -u USER:PASSWD http://<nextcloud_host>/index.php/apps/integration_openproject/direct-upload-token -d '{"folder_id":<folder_id>}' -H'Content-Type: application/json'The response from the above curl request will be
{ "token": "<token>", "expires_on": <some_timestamp> }Note: The token is one-time only.
-
Direct upload: Send a multipart form data POST request to the
direct-uploadend-point to upload the file withtokenacquired from the preparation endpoint. The API takes an optional parameteroverwrite.-
Direct upload without overwrite parameter: If the
overwriteparameter is not set, a file will only be uploaded if no file exists with that name, otherwise a conflict error is thrown.curl -X POST 'http://<nextcloud_host>/index.php/apps/integration_openproject/direct-upload/<token>' \ --form 'file=@"<path-of-file>"' -H'Content-Type: multipart/form-data'
The response from the above curl request will be
{ "file_name": "<file_name>", "file_id": <file_id> } -
Direct upload with overwrite parameter: The overwrite parameter can be either set to
trueorfalse.-
overwrite set to false: If the parameter is set to
falseand a file with the name already exists, a new file will be uploaded with the existing name and a number suffix.curl -X POST 'http://<nextcloud_host>/index.php/apps/integration_openproject/direct-upload/<token>' \ --form 'file=@"<path-of-file>"' --form 'overwrite="false"' -H'Content-Type: multipart/form-data'
The response from the above curl request will be
{ "file_name": "<file_name>(some-number).ext", "file_id": <file_id> } -
overwrite set to true: If the parameter is set to
trueand a file with the name already exists, the existing file will be overwritten.curl -X POST 'http://<nextcloud_host>/index.php/apps/integration_openproject/direct-upload/<token>' \ --form 'file=@"<path-of-file>"' --form 'overwrite="true"' -H'Content-Type: multipart/form-data'
The response from the above curl request will be
{ "file_name": "<file_name>", "file_id": <file_id> }Suppose we have a file with name
file.txtin the server, and we send a request to direct-upload api with filefile.txtand overwrite set totruethen the response will be:{ "file_name": "file (2).txt", "file_id": 123 }Note: The file id in this case is the id of the original file. Only the content is overwritten.
-
-
Develop using docker compose
Requirements:
-
Node.js (>=v14.0.0)
-
NPM (>=v7.0.0)
-
Docker (>=v19.03.0)
-
Docker Compose
- for v1, minimum version required is v1.29.0, make sure to use
docker-composeinstead ofdocker compose - this guide is written for v2
- for v1, minimum version required is v1.29.0, make sure to use
-
OpenProject server instance
It must be reachable by the hostname
host.docker.internalin the host machine. You can do this through this environment variable:OPENPROJECT_DEV_EXTRA_HOSTS=host.docker.internal.It must also use hostname
host.docker.internal:3000instead oflocalhost:3000in the settings. Change it in Administration > System settings > General > Host name, or through the environment variableOPENPROJECT_HOST__NAME=host.docker.internal:3000.host.docker.internalwill resolve to127.0.0.1on the docker host and to something like172.17.0.1inside of the docker services, so OpenProject needs to listen to those addresses. For that use the-boption if you are running OpenProject manually e.g.bin/rails server -b 0.0.0.0or when using foreman setHOST=0.0.0.0as env. variable.The whole OpenProject start command might look something like:
- manual start:
OPENPROJECT_DEV_EXTRA_HOSTS=host.docker.internal OPENPROJECT_HOST__NAME=host.docker.internal:3000 RAILS_ENV=development bin/rails server -b 0.0.0.0 - using foreman:
HOST=0.0.0.0 OPENPROJECT_DEV_EXTRA_HOSTS=host.docker.internal OPENPROJECT_HOST__NAME=host.docker.internal:3000 foreman start -f Procfile.dev
For more information see: OpenProject documentation
- manual start:
-
OpenProject Integration app
# the app needs to be cloned inside the "custom_apps" dir
mkdir $HOME/development/custom_apps -p
cd $HOME/development/custom_apps
git clone https://github.com/nextcloud/integration_openproject.git
# installation & building
cd integration_openproject
npm ci
npm run build
# provide group ownership of "custom_apps" to the user "www-data"
sudo chgrp www-data $HOME/development/custom_apps -R
sudo chmod g+w $HOME/development/custom_apps -R- APP_DIR
- description: location where the
integration_openprojectrepository is cloned - default:
./../../custom_apps
- description: location where the
It is highly recommended to regularly update the included containers.
docker compose pullNow, run the containers. In order to expose a port of the nextcloud containers, make sure to provide
a docker-compose.override.yml specifying the exposed ports. In this example, we assume you simply use the content of
the provided docker-compose.override.example.yml, which exposes port 8080.
cp docker-compose.override.example.yml docker-compose.override.yml
docker compose upNote: If you've cloned the integration app anywhere other that the default ./../../custom_apps, provide its path
in the APP_DIR environment variable
APP_DIR=<path-to-integration-app> docker compose upAfter this, you should be able to access the Nextcloud server at http://localhost:8080.
Note: These steps will only be necessary for the first setup.
With our compose setup, there are two options for the database:
- SQLite: No specific configuration is necessary
- PostgreSQL:
- Database:
nextcloud - User:
nextcloud - Password:
nextcloud
- Database:
The NC server installation can be done in two ways:
-
With
occcommand (CLI):- Using
PostgreSQLas database type:docker compose exec --user www-data nextcloud php occ maintenance:install -vvv \ --database pgsql \ --database-name nextcloud \ --database-host db \ --database-user nextcloud \ --database-pass nextcloud \ --admin-user admin \ --admin-pass admin \ --data-dir /var/www/html/data - Using
SQLiteas database type:docker compose exec --user www-data nextcloud php occ maintenance:install -vvv \ --admin-user admin \ --admin-pass admin \ --data-dir /var/www/html/data
- Using
-
With the
browser(WebUI):- Browse to http://localhost:8080
- Fill
Create an admin accountform - Choose the database type
- Click the
Installbutton
You can browse as admin to the apps center and enable it using the webUI, or you can just use the terminal as:
docker compose exec --user www-data nextcloud php occ a:e integration_openprojectdocker compose exec --user www-data nextcloud php occ config:system:set allow_local_remote_servers --value 1- as NextCloud admin browse to Settings->Administration->OpenProject
- configure the connection to OpenProject using
http://host.docker.internal:3000as the OpenProject URL - in OpenProject use
http://localhost:8080as the NextCloud URL
If the bearer tokens are not forwarded to Nextcloud the authorization cannot work and that needs to be detected by OpenProject.
Easiest way to do that is to disable mod_rewrite in Apache:
docker compose exec nextcloud a2dismod rewrite
docker compose exec nextcloud service apache2 restartTo enable it again, run:
docker compose exec nextcloud a2enmod rewrite
docker compose exec nextcloud service apache2 restartTo test another version of Nextcloud change the nextcloud images in the docker-compose.override.yml
e.g:
services:
nextcloud:
image: nextcloud:24-apache
ports:
- "8080:80"
cron:
image: nextcloud:24-apachePlease note:
- Only apache based versions will work
- Nextcloud does not support downgrading. If you want to go back to an older version, you need to delete all the volumes with
docker compose down -vand start the Nextcloud installation again
Nextcloud can work with or without index.php in the URL. The connection to OpenProject has to work regardless of how it is configured.
By default, the docker setup in this repo starts Nextcloud without index.php in the URL. To change that, we have to edit the .htaccess file. The code that is responsible to rewrite the URLs and make them prettier is attached at the bottom of the .htaccess file in the Nextcloud folder.
It looks like that:
#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####
ErrorDocument 403 /
ErrorDocument 404 /
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]
RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]
...
</IfModule>
If you haven't changed anything else in the .htaccess file, deleting everything below #### DO NOT CHANGE ANYTHING ABOVE THIS LINE #### will reset the file to a state where it does not rewrite the URLs.
You can use sed to do it in one command:
docker compose exec --user www-data nextcloud sed -i '/#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####/,$d' .htaccessTo remove index.php again from the URL run
docker compose exec --user www-data nextcloud php occ maintenance:update:htaccessThis will put the rewrite rules back into the .htaccess file.
The default docker configuration serves Nextcloud from the root of the domain (http://localhost:8080/), but it is also possible to serve it from a sub folder e.g. http://localhost:8080/nextcloud/. To do that with the existing docker configuration, there are a couple of steps to take.
- configure apache to serve the parent folder as
DocumentRoot:docker compose exec nextcloud sed -i 's/DocumentRoot \/var\/www\/html/DocumentRoot \/var\/www/' /etc/apache2/sites-enabled/000-default.conf
- configure apache to accept settings from
.htaccesson any level:docker compose exec nextcloud sed -i 's/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
- restart apache:
docker compose exec nextcloud service apache2 restart - delete existing Nextcloud configuration for pretty URLs as it's set to the root folder
docker compose exec --user www-data nextcloud rm config/apache-pretty-urls.config.php - set the sub folder as the new base for pretty urls:
docker compose exec --user www-data nextcloud php occ config:system:set htaccess.RewriteBase --value '/html/' docker compose exec --user www-data nextcloud php occ config:system:set overwrite.cli.url --value 'http://localhost/html' docker compose exec --user www-data nextcloud php occ maintenance:update:htaccess
Now, you should be able to reach the Nextcloud installation at http://localhost:8080/html/
Now you can watch for the app code changes using the following command and start developing.
cd $HOME/development/custom_apps/integration_openproject
npm run watch- Create a release branch from master with the name
release/<version>e.g.release/2.1 - Protect that new branch the same way as
master - On the release branch update the version in
appinfo/info.xml - Do QA and fixes of bugs in the release branch
- Merge the release branch into the
masterbranch, to get all good changes also into the current development
- On the release branch of the current minor version update the version in
appinfo/info.xml(not needed for nightly builds) - Merge the release branch into the
masterbranch, to get all good changes also into the current development
- Tag a commit on the
release/<version>branch. The tag must have the formatv2.1.1for releases andv2.1.1-20220928-nightlyfor nightly builds.
e.g:git tag v2.0.6-20220928-nightly -m "v2.0.6-20220928-nightly" - Push the tag to the
auto-releasebranch:git push origin release/<version>:auto-release --tags -f - Approve the deployment in GitHub actions