Skip to content

Commit

Permalink
Merge branch 'master' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
arteymix committed Dec 16, 2023
2 parents cdc618a + b839079 commit afa27b5
Show file tree
Hide file tree
Showing 37 changed files with 1,529 additions and 138 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4.0.0
- uses: actions/checkout@v4.1.1
with:
lfs: true
- name: Setup Java JDK
uses: actions/setup-java@v3.12.0
uses: actions/setup-java@v3.13.0
with:
distribution: temurin
java-version: '8'
- name: Setup Node.js
uses: actions/[email protected].1
uses: actions/[email protected].2
with:
node-version: 16
- name: Test code with Maven
Expand Down
74 changes: 38 additions & 36 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
mysql56:
image: mysql:5.6
ports:
- "3306:3306"
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=ThePassword
- MYSQL_DATABASE=db_example
- MYSQL_RANDOM_ROOT_PASSWORD=true
mysql57:
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=ThePassword
- MYSQL_DATABASE=db_example
- MYSQL_RANDOM_ROOT_PASSWORD=true
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=ThePassword
- MYSQL_DATABASE=db_example
- MYSQL_RANDOM_ROOT_PASSWORD=true
mariadb:
image: mariadb:10.6
ports:
- "3306:3306"
environment:
- MARIADB_USER=springuser
- MARIADB_PASSWORD=ThePassword
- MARIADB_DATABASE=db_example
- MARIADB_RANDOM_ROOT_PASSWORD=true
version: "3.8"
services:
mysql56:
image: mysql:5.6
ports:
- "3306:3306"
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=ThePassword
- MYSQL_DATABASE=db_example
- MYSQL_RANDOM_ROOT_PASSWORD=true
mysql57:
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=ThePassword
- MYSQL_DATABASE=db_example
- MYSQL_RANDOM_ROOT_PASSWORD=true
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_USER=springuser
- MYSQL_PASSWORD=ThePassword
- MYSQL_DATABASE=db_example
- MYSQL_RANDOM_ROOT_PASSWORD=true
mariadb:
image: mariadb:10.6
ports:
- "3306:3306"
environment:
- MARIADB_USER=springuser
- MARIADB_PASSWORD=ThePassword
- MARIADB_DATABASE=db_example
- MARIADB_RANDOM_ROOT_PASSWORD=true
85 changes: 77 additions & 8 deletions docs/customization.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,50 @@
# Customize your instance

This section contains instruction to customize your RDP registry.

## Allowed email providers (new in 1.5.8)

You may restrict which email providers can be used for creating new accounts by specifying a list or a file
containing allowed domains. Matches are performed in a case-insensitive manner. Only printable ASCII characters are
allowed.

```ini
rdp.settings.allowed-email-domains=example.com
rdp.settings.allowed-email-domains-file=file:swot.txt
rdp.settings.allowed-email-domains-file-refresh-delay=3600
```

The default refresh delay is set to one hour. Disable it by setting it to an empty value. A value of `0` will cause a
refresh on every validation.

This feature is disabled by default.

### Internationalized domain names

To use [internationalized domain names](https://en.wikipedia.org/wiki/Internationalized_domain_name) in email addresses,
add their Punycode to the list or file and set the following setting:

```ini
rdp.settings.allow-internationalized-email-domains=true
```

For example, to allow users from `universität.example.com` to register, add `xn--universitt-y5a.example.com` to the
file.

## reCAPTCHA (new in 1.5.8)

RDP supports [reCAPTCHA v2](https://www.google.com/recaptcha/about/) to mitigate the registration of accounts by bots.
To enable it, add the reCAPTCHA token and secret to your configuration.

```ini
rdp.site.recaptcha-token=mytoken
rdp.site.recaptcha-secret=mysecret
```

This feature is disabled by default.

## Cached data

Most of the data used by the application is retrieved remotely at startup and subsequently updated on a monthly basis.

To prevent data from being loaded on startup and/or recurrently, set the following parameter in
Expand All @@ -12,6 +57,8 @@ rdp.settings.cache.enabled=false
You should deploy your RDP instance at least once to have initial data before setting this property and whenever you
update the software.

The following sections will cover in details individual data sources that can be imported in your registry.

## Gene information and GO terms

By default, RDP will retrieve the latest gene information from NCBI, and GO terms
Expand Down Expand Up @@ -69,6 +116,29 @@ where taxon_id = 10090;

Every time new model systems are added to the application, they will have to be activated in this manner.

## GO term recommendation

Users can receive recommended terms based on the TIER1 and TIER2 genes they have added to their profiles.

The recommendation algorithm works as follows:

1. Retrieve GO terms associated to all TIER1 and TIER2 genes
2. Retrieve all the descendants of these terms
3. For each term, compute how many TIER1 or TIER2 genes they are associated either directly or indirectly via their
descendants
4. Keep terms that are not already on the user profile and that mention at least 2 TIER1 or TIER2 genes
5. Exclude terms with more than 50 associated genes
6. Retain terms that have at least one novel gene that is not on the user's profile
7. Retain most specific terms if a given term and its descendant is recommended

You can adjust the number of overlapping TIER1 or TIER2 genes and the maximum size of a GO term by setting the
following:

```ini
rdp.settings.go-term-min-overlap=2 # new in 1.5.8
rdp.settings.go-term-size-limit=50
```

### Customizing taxon appearance (new in 1.5.5)

By default, taxon are rendered using the common name in title case. The only exception is for *Homo sapiens* which
Expand Down Expand Up @@ -271,19 +341,20 @@ The page lists some basic stats at the very top and provides few action buttons:

![Actions available for simple categories.](images/simple-category-actions.png)

- "Deactivate" (or "Deactivate All Terms" in the case of an ontology category): this will remove the category from the Profile and Search pages. This action is reversible, as the category can be easily re-activated. This action is recommended in cases where a category cannot be deleted because it has already been used by some users.
- "Deactivate" (or "Deactivate All Terms" in the case of an ontology category): this will remove the category from the
Profile and Search pages. This action is reversible, as the category can be easily re-activated. This action is
recommended in cases where a category cannot be deleted because it has already been used by some users.

- Update from "source": Update the ontology category using the original URL (if available)

- Download as OBO: Download the category as an OBO file



The number of used terms indicate how many terms in the ontology have been associated with associated with users.

In the Edit window on the Manage Profile Category page, you can add a definition/description of the category, which
is used in a tooltip on the Profile Page. You can also specify if this category will be used as a filter on the Gene
Search page. While all active categories will be available on the Researcher Search page, only categories that have "Available for gene search?" checked will be displayed on the Gene Search page.
Search page. While all active categories will be available on the Researcher Search page, only categories that have "
Available for gene search?" checked will be displayed on the Gene Search page.

![Interface for editing the properties of an ontology.](images/edit-an-ontology.png)

Expand Down Expand Up @@ -348,8 +419,6 @@ values. A warning will be displayed in the admin section if this is the case.
Read more about configuring messages in [Customizing the application messages](#customizing-the-applications-messages)
section of this page.



### Resolving external URLs

By default, ontologies and terms are resolved from [OLS](https://www.ebi.ac.uk/ols/index). Reactome pathways get a
Expand Down Expand Up @@ -402,7 +471,6 @@ settings will retrieve all the necessary files relative to the working directory
#this setting relates only to gene info files. Files for all taxons will be stord under gene/
rdp.settings.cache.load-from-disk=true
rdp.settings.cache.gene-files-location=file:genes/

#file for GO ontology
rdp.settings.cache.term-file=file:go.obo
#file for gene GO annotation
Expand Down Expand Up @@ -537,7 +605,8 @@ rdp.faq.questions.<q_key>=A relevant question.
rdp.faq.answers.<q_key>=A plausible answer.
```

The provided default file can be found in [faq.properties](https://github.com/PavlidisLab/rdp/tree/{{ config.extra.git_ref }}/src/main/resources/faq.properties).
The provided default file can be found in [faq.properties](https://github.com/PavlidisLab/rdp/tree/{{
config.extra.git_ref }}/src/main/resources/faq.properties).

### Ordering FAQ entries

Expand Down
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.13.0</version>
<version>2.15.0</version>
</dependency>

<dependency>
Expand All @@ -152,14 +152,14 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.10.0</version>
<version>1.11.0</version>
</dependency>

<!-- User-Agent header parsing -->
<dependency>
<groupId>nl.basjes.parse.useragent</groupId>
<artifactId>yauaa</artifactId>
<version>7.22.0</version>
<version>7.24.0</version>
</dependency>

<!-- Testing Support -->
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/ubc/pavlab/rdp/ValidationConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package ubc.pavlab.rdp;

import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.convert.DurationUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import ubc.pavlab.rdp.validation.*;

import java.io.IOException;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
* This configuration provides a few {@link org.springframework.validation.Validator} beans.
*/
@CommonsLog
@Configuration
public class ValidationConfig {

@Bean
public EmailValidator emailValidator(
@Value("${rdp.settings.allowed-email-domains}") List<String> allowedEmailDomains,
@Value("${rdp.settings.allowed-email-domains-file}") Resource allowedEmailDomainsFile,
@Value("${rdp.settings.allowed-email-domains-file-refresh-delay}") @DurationUnit(ChronoUnit.SECONDS) Duration refreshDelay,
@Value("${rdp.settings.allow-internationalized-email-domains}") boolean allowIdn ) throws IOException {
List<AllowedDomainStrategy> strategies = new ArrayList<>();
if ( allowedEmailDomains != null && !allowedEmailDomains.isEmpty() ) {
SetBasedAllowedDomainStrategy strategy = new SetBasedAllowedDomainStrategy( allowedEmailDomains );
strategies.add( strategy );
log.info( String.format( "Email validation is configured to accept addresses from: %s.", String.join( ", ",
strategy.getAllowedDomains() ) ) );
}
if ( allowedEmailDomainsFile != null ) {
log.info( "Reading allowed email domains from " + allowedEmailDomainsFile + "..." );
if ( refreshDelay.isZero() ) {
log.warn( "The refresh delay for reading " + allowedEmailDomainsFile + " is set to zero: the file will be re-read for every email domain validation." );
}
ResourceBasedAllowedDomainStrategy strategy = new ResourceBasedAllowedDomainStrategy( allowedEmailDomainsFile, refreshDelay );
strategy.refresh();
Set<String> allowedDomains = strategy.getAllowedDomains();
strategies.add( strategy );
if ( strategy.getAllowedDomains().size() <= 5 ) {
log.info( String.format( "Email validation is configured to accept addresses from: %s.", String.join( ", ", allowedDomains ) ) );
} else {
log.info( String.format( "Email validation is configured to accept addresses from a list of %d domains.", allowedDomains.size() ) );
}
}
AllowedDomainStrategy strategy;
if ( strategies.isEmpty() ) {
strategy = ( domain ) -> true;
log.warn( "No allowed email domains file specified, all domains will be allowed for newly registered users." );
} else if ( strategies.size() == 1 ) {
strategy = strategies.iterator().next();
} else {
strategy = domain -> strategies.stream().anyMatch( s -> s.allows( domain ) );
}
return new EmailValidator( strategy, allowIdn );
}

@Bean
@ConditionalOnProperty("rdp.site.recaptcha-secret")
public RecaptchaValidator recaptchaValidator( @Value("${rdp.site.recaptcha-secret}") String secret ) {
RestTemplate rt = new RestTemplate();
rt.getMessageConverters().add( new FormHttpMessageConverter() );
return new RecaptchaValidator( rt, secret );
}
}
5 changes: 5 additions & 0 deletions src/main/java/ubc/pavlab/rdp/controllers/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public class AdminController {
@Qualifier("adminTaskExecutor")
private AsyncTaskExecutor taskExecutor;

@InitBinder("user")
public void configureUserInitBinder( WebDataBinder dataBinder ) {
dataBinder.setAllowedFields( "email", "profile.name" );
}

/**
* List all users
*/
Expand Down
Loading

0 comments on commit afa27b5

Please sign in to comment.