From bec0ed52110df570a0c56b245b741ae961a97d07 Mon Sep 17 00:00:00 2001 From: pfurio Date: Wed, 17 Apr 2024 15:53:21 +0200 Subject: [PATCH 01/20] catalog: implement update user information for admins, #TASK-6013 --- .../opencga/catalog/db/api/UserDBAdaptor.java | 4 +- .../db/mongodb/UserMongoDBAdaptor.java | 9 +- .../catalog/managers/OrganizationManager.java | 66 +++++++++++ .../opencga/catalog/managers/UserManager.java | 2 +- .../opencga/catalog/utils/ParamUtils.java | 16 +++ .../catalog/managers/CatalogManagerTest.java | 25 ++++ .../managers/OrganizationManagerTest.java | 75 +++++++++++- .../user/OrganizationUserUpdateParams.java | 109 ++++++++++++++++++ .../core/models/user/UserUpdateParams.java | 27 +---- .../server/rest/OrganizationWSServer.java | 24 ++++ 10 files changed, 320 insertions(+), 37 deletions(-) create mode 100644 opencga-core/src/main/java/org/opencb/opencga/core/models/user/OrganizationUserUpdateParams.java diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java index 8a6c7207968..045e50d7f26 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java @@ -123,8 +123,8 @@ enum QueryParams implements QueryParam { ACCOUNT("account", TEXT_ARRAY, ""), ACCOUNT_AUTHENTICATION_ID("account.authentication.id", TEXT, ""), ACCOUNT_CREATION_DATE("account.creationDate", TEXT, ""), - SIZE("size", INTEGER_ARRAY, ""), - QUOTA("quota", INTEGER_ARRAY, ""), + ACCOUNT_EXPIRATION_DATE("account.expirationDate", TEXT, ""), + QUOTA("quota", OBJECT, ""), ATTRIBUTES("attributes", TEXT, ""), // "Format: where is [<|<=|>|>=|==|!=|~|!~]" PROJECTS("projects", TEXT_ARRAY, ""), diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java index a8db293e258..6c08e34c536 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java @@ -441,9 +441,12 @@ public OpenCGAResult update(Query query, ObjectMap parameters, QueryOptions quer userParameters.put(QueryParams.INTERNAL_STATUS_ID.key(), parameters.get(QueryParams.INTERNAL_STATUS_ID.key())); userParameters.put(QueryParams.INTERNAL_STATUS_DATE.key(), TimeUtils.getTime()); } + if (parameters.containsKey(ACCOUNT_EXPIRATION_DATE.key())) { + userParameters.put(ACCOUNT_EXPIRATION_DATE.key(), parameters.get(ACCOUNT_EXPIRATION_DATE.key())); + } - final String[] acceptedLongParams = {QueryParams.QUOTA.key(), QueryParams.SIZE.key()}; - filterLongParams(parameters, userParameters, acceptedLongParams); + final String[] acceptedObjectParams = {QueryParams.QUOTA.key()}; + filterObjectParams(parameters, userParameters, acceptedObjectParams); final String[] acceptedMapParams = {QueryParams.ATTRIBUTES.key()}; filterMapParams(parameters, userParameters, acceptedMapParams); @@ -671,8 +674,6 @@ private Bson parseQuery(Query query) throws CatalogDBException { case EMAIL: case ORGANIZATION: case INTERNAL_STATUS_DATE: - case SIZE: - case QUOTA: case ACCOUNT_AUTHENTICATION_ID: case ACCOUNT_CREATION_DATE: case TOOL_ID: diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java index 9201e9c6b3e..65d5b4f4ace 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java @@ -29,10 +29,13 @@ import org.opencb.opencga.core.models.common.Enums; import org.opencb.opencga.core.models.common.InternalStatus; import org.opencb.opencga.core.models.organizations.*; +import org.opencb.opencga.core.models.user.OrganizationUserUpdateParams; +import org.opencb.opencga.core.models.user.User; import org.opencb.opencga.core.response.OpenCGAResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; import java.util.*; public class OrganizationManager extends AbstractManager { @@ -306,6 +309,69 @@ public OpenCGAResult update(String organizationId, OrganizationUpd return result; } + public OpenCGAResult updateUser(@Nullable String organizationId, String userId, OrganizationUserUpdateParams updateParams, + QueryOptions options, String token) throws CatalogException { + JwtPayload tokenPayload = catalogManager.getUserManager().validateToken(token); + + ObjectMap auditParams = new ObjectMap() + .append("organizationId", organizationId) + .append("userId", userId) + .append("updateParams", updateParams) + .append("options", options) + .append("token", token); + + options = ParamUtils.defaultObject(options, QueryOptions::new); + try { + String myOrganizationId = StringUtils.isNotEmpty(organizationId) ? organizationId : tokenPayload.getOrganization(); + authorizationManager.checkIsAtLeastOrganizationOwnerOrAdmin(myOrganizationId, tokenPayload.getUserId(organizationId)); + ParamUtils.checkObj(updateParams, "OrganizationUserUpdateParams"); + getUserDBAdaptor(organizationId).checkId(userId); + + if (StringUtils.isNotEmpty(updateParams.getEmail())) { + ParamUtils.checkEmail(updateParams.getEmail()); + } + if (updateParams.getQuota() != null) { + if (updateParams.getQuota().getDiskUsage() < 0) { + throw new CatalogException("Disk usage cannot be negative"); + } + if (updateParams.getQuota().getCpuUsage() < 0) { + throw new CatalogException("CPU usage cannot be negative"); + } + if (updateParams.getQuota().getMaxDisk() < 0) { + throw new CatalogException("Max disk cannot be negative"); + } + if (updateParams.getQuota().getMaxCpu() < 0) { + throw new CatalogException("Max CPU cannot be negative"); + } + } + if (updateParams.getAccount() != null && StringUtils.isNotEmpty(updateParams.getAccount().getExpirationDate())) { + ParamUtils.checkDateIsNotExpired(updateParams.getAccount().getExpirationDate(), "expirationDate"); + } + + ObjectMap updateMap; + try { + updateMap = updateParams.getUpdateMap(); + } catch (JsonProcessingException e) { + throw new CatalogException("Could not parse OrganizationUserUpdateParams object: " + e.getMessage(), e); + } + OpenCGAResult updateResult = getUserDBAdaptor(myOrganizationId).update(userId, updateMap); + auditManager.auditUpdate(organizationId, tokenPayload.getUserId(organizationId), Enums.Resource.USER, userId, "", "", "", + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); + + if (options.getBoolean(ParamConstants.INCLUDE_RESULT_PARAM)) { + // Fetch updated user + OpenCGAResult result = getUserDBAdaptor(organizationId).get(userId, options); + updateResult.setResults(result.getResults()); + } + + return updateResult; + } catch (CatalogException e) { + auditManager.auditUpdate(organizationId, tokenPayload.getUserId(organizationId), Enums.Resource.USER, userId, "", "", "", + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError())); + throw e; + } + } + private void validateOrganizationForCreation(Organization organization, String userId) throws CatalogParameterException { ParamUtils.checkParameter(organization.getId(), OrganizationDBAdaptor.QueryParams.ID.key()); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index 96098fedcff..b54a9fa0ef3 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -590,7 +590,7 @@ public OpenCGAResult update(String userId, ObjectMap parameters, QueryOpti userId = getValidUserId(userId, payload); for (String s : parameters.keySet()) { - if (!s.matches("name|email|organization|attributes")) { + if (!s.matches("name|email")) { throw new CatalogDBException("Parameter '" + s + "' can't be changed"); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java index 7d6eb326acc..60649298155 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/ParamUtils.java @@ -174,6 +174,22 @@ public static void checkDateFormat(String creationDate, String param) throws Cat } } + public static void checkDateIsNotExpired(String dateStr, String param) throws CatalogParameterException { + if (StringUtils.isEmpty(dateStr)) { + throw CatalogParameterException.isNull(param); + } else { + // Validate date can be parsed and has the proper format + Date date = TimeUtils.toDate(dateStr); + if (date == null || dateStr.length() != 14) { + throw new CatalogParameterException("Unexpected '" + param + "' format. Expected format is 'yyyyMMddHHmmss'"); + } + if (date.before(TimeUtils.getDate())) { + throw new CatalogParameterException("The date for '" + param + "' introduced is already expired. Please, introduce a valid" + + " date in the future."); + } + } + } + public static String checkDateOrGetCurrentDate(String date, String param) throws CatalogParameterException { if (StringUtils.isEmpty(date)) { return TimeUtils.getTime(); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index 07edb4610b7..df98ce12de5 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -16,6 +16,7 @@ package org.opencb.opencga.catalog.managers; +import com.fasterxml.jackson.core.JsonProcessingException; import com.mongodb.BasicDBObject; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; @@ -59,6 +60,7 @@ import org.opencb.opencga.core.models.user.Account; import org.opencb.opencga.core.models.user.AuthenticationResponse; import org.opencb.opencga.core.models.user.User; +import org.opencb.opencga.core.models.user.UserUpdateParams; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; @@ -70,6 +72,7 @@ import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.*; +import static org.opencb.opencga.core.common.JacksonUtils.getUpdateObjectMapper; @Category(MediumTests.class) public class CatalogManagerTest extends AbstractManagerTest { @@ -224,6 +227,28 @@ public void anonymousUserLoginTest() throws CatalogException { catalogManager.getUserManager().loginAnonymous(org2); } + @Test + public void updateUserTest() throws JsonProcessingException, CatalogException { + UserUpdateParams userUpdateParams = new UserUpdateParams() + .setName("newName") + .setEmail("mail@mail.com"); + ObjectMap updateParams = new ObjectMap(getUpdateObjectMapper().writeValueAsString(userUpdateParams)); + User user = catalogManager.getUserManager().update(normalUserId1, updateParams, INCLUDE_RESULT, normalToken1).first(); + assertEquals(userUpdateParams.getName(), user.getName()); + assertEquals(userUpdateParams.getEmail(), user.getEmail()); + + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().update(normalUserId1, updateParams, INCLUDE_RESULT, normalToken2)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().update(normalUserId1, updateParams, INCLUDE_RESULT, opencgaToken)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().update(normalUserId1, updateParams, INCLUDE_RESULT, ownerToken)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().update(normalUserId1, updateParams, INCLUDE_RESULT, orgAdminToken1)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().update(normalUserId1, updateParams, INCLUDE_RESULT, studyAdminToken1)); + + userUpdateParams = new UserUpdateParams() + .setEmail("notAnEmail"); + ObjectMap updateParams2 = new ObjectMap(getUpdateObjectMapper().writeValueAsString(userUpdateParams)); + assertThrows(CatalogParameterException.class, () -> catalogManager.getUserManager().update(normalUserId1, updateParams2, INCLUDE_RESULT, normalToken1)); + } + @Test public void testGetUserInfo() throws CatalogException { // OpenCGA administrator diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java index 9cbcb43c091..13d9feaea3e 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java @@ -10,22 +10,24 @@ import org.opencb.opencga.catalog.db.api.StudyDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; import org.opencb.opencga.catalog.exceptions.CatalogException; +import org.opencb.opencga.catalog.exceptions.CatalogParameterException; import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.core.api.ParamConstants; +import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.AuthenticationOrigin; import org.opencb.opencga.core.models.organizations.Organization; import org.opencb.opencga.core.models.organizations.OrganizationConfiguration; import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; import org.opencb.opencga.core.models.study.Group; import org.opencb.opencga.core.models.study.Study; +import org.opencb.opencga.core.models.user.OrganizationUserUpdateParams; +import org.opencb.opencga.core.models.user.User; +import org.opencb.opencga.core.models.user.UserQuota; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import static org.junit.Assert.*; @@ -87,6 +89,71 @@ public void updateAuthOriginTest() throws CatalogException { assertEquals(authOrigin.getAlgorithm(), organization.getConfiguration().getAuthenticationOrigins().get(0).getAlgorithm()); } + @Test + public void validateUserUpdateParamsTest() { + OrganizationUserUpdateParams expiredDateParam = new OrganizationUserUpdateParams() + .setAccount(new OrganizationUserUpdateParams.Account("20200101100000")); + CatalogParameterException exception = assertThrows(CatalogParameterException.class, () -> catalogManager.getOrganizationManager() + .updateUser(organizationId, normalUserId1, expiredDateParam, INCLUDE_RESULT, ownerToken)); + assertTrue(exception.getMessage().contains("expired")); + + OrganizationUserUpdateParams invalidMailParam = new OrganizationUserUpdateParams() + .setEmail("invalidEmail"); + exception = assertThrows(CatalogParameterException.class, () -> catalogManager.getOrganizationManager().updateUser(organizationId, + normalUserId1, invalidMailParam, INCLUDE_RESULT, ownerToken)); + assertTrue(exception.getMessage().contains("not valid")); + } + + @Test + public void updateUserInformationTest() throws CatalogException { + Date date = TimeUtils.getDate(); + Calendar cl = Calendar.getInstance(); + cl.setTime(date); + cl.add(Calendar.YEAR, 1); + String expirationTime = TimeUtils.getTime(cl.getTime()); + + OrganizationUserUpdateParams userUpdateParams = new OrganizationUserUpdateParams() + .setName("newName") + .setEmail("mail@mail.com") + .setAccount(new OrganizationUserUpdateParams.Account(expirationTime)) + .setQuota(new UserQuota(1000, 1000000, 1000, 1000000)) + .setAttributes(Collections.singletonMap("key1", "value1")); + updateAndAssertChanges(userUpdateParams, opencgaToken); + + userUpdateParams = new OrganizationUserUpdateParams() + .setName("newName2") + .setEmail("mai2l@mail.com") + .setAccount(new OrganizationUserUpdateParams.Account(expirationTime)) + .setQuota(new UserQuota(1001, 1010000, 1010, 1100000)) + .setAttributes(Collections.singletonMap("key2", "value2")); + updateAndAssertChanges(userUpdateParams, ownerToken); + + userUpdateParams = new OrganizationUserUpdateParams() + .setName("newName3") + .setEmail("mai3l@mail.com") + .setAccount(new OrganizationUserUpdateParams.Account(expirationTime)) + .setQuota(new UserQuota(3001, 1010300, 1013, 1300000)) + .setAttributes(Collections.singletonMap("key3", "value3")); + updateAndAssertChanges(userUpdateParams, orgAdminToken1); + + thrown.expect(CatalogAuthorizationException.class); + catalogManager.getOrganizationManager().updateUser(organizationId, normalUserId1, userUpdateParams, INCLUDE_RESULT, normalToken1); + } + + private void updateAndAssertChanges(OrganizationUserUpdateParams userUpdateParams, String token) throws CatalogException { + User user = catalogManager.getOrganizationManager().updateUser(organizationId, normalUserId1, userUpdateParams, INCLUDE_RESULT, token).first(); + assertEquals(userUpdateParams.getName(), user.getName()); + assertEquals(userUpdateParams.getEmail(), user.getEmail()); + assertEquals(userUpdateParams.getAccount().getExpirationDate(), user.getAccount().getExpirationDate()); + assertEquals(userUpdateParams.getQuota().getCpuUsage(), user.getQuota().getCpuUsage()); + assertEquals(userUpdateParams.getQuota().getDiskUsage(), user.getQuota().getDiskUsage()); + assertEquals(userUpdateParams.getQuota().getMaxCpu(), user.getQuota().getMaxCpu()); + assertEquals(userUpdateParams.getQuota().getMaxDisk(), user.getQuota().getMaxDisk()); + for (String key : userUpdateParams.getAttributes().keySet()) { + assertEquals(userUpdateParams.getAttributes().get(key), user.getAttributes().get(key)); + } + } + @Test public void migrationExecutionProjectionTest() throws CatalogException { Organization organization = catalogManager.getOrganizationManager().get(organizationId, null, ownerToken).first(); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/user/OrganizationUserUpdateParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/OrganizationUserUpdateParams.java new file mode 100644 index 00000000000..ce30fd63c41 --- /dev/null +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/OrganizationUserUpdateParams.java @@ -0,0 +1,109 @@ +package org.opencb.opencga.core.models.user; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.opencb.commons.datastore.core.ObjectMap; + +import java.util.Map; + +import static org.opencb.opencga.core.common.JacksonUtils.getUpdateObjectMapper; + +public class OrganizationUserUpdateParams extends UserUpdateParams { + + private UserQuota quota; + private Account account; + private Map attributes; + + public OrganizationUserUpdateParams() { + } + + public OrganizationUserUpdateParams(String name, String email, UserQuota quota, Account account, Map attributes) { + super(name, email); + this.quota = quota; + this.account = account; + this.attributes = attributes; + } + + @JsonIgnore + public ObjectMap getUpdateMap() throws JsonProcessingException { + return new ObjectMap(getUpdateObjectMapper().writeValueAsString(this)); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("OrganizationUserUpdateParams{"); + sb.append("quota=").append(quota); + sb.append(", account=").append(account); + sb.append(", attributes=").append(attributes); + sb.append('}'); + return sb.toString(); + } + + public UserQuota getQuota() { + return quota; + } + + public OrganizationUserUpdateParams setQuota(UserQuota quota) { + this.quota = quota; + return this; + } + + public Account getAccount() { + return account; + } + + public OrganizationUserUpdateParams setAccount(Account account) { + this.account = account; + return this; + } + + public Map getAttributes() { + return attributes; + } + + public OrganizationUserUpdateParams setAttributes(Map attributes) { + this.attributes = attributes; + return this; + } + + @Override + public OrganizationUserUpdateParams setName(String name) { + super.setName(name); + return this; + } + + @Override + public OrganizationUserUpdateParams setEmail(String email) { + super.setEmail(email); + return this; + } + + public static class Account { + private String expirationDate; + + public Account() { + } + + public Account(String expirationDate) { + this.expirationDate = expirationDate; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Account{"); + sb.append("expirationDate='").append(expirationDate).append('\''); + sb.append('}'); + return sb.toString(); + } + + public String getExpirationDate() { + return expirationDate; + } + + public Account setExpirationDate(String expirationDate) { + this.expirationDate = expirationDate; + return this; + } + } + +} diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserUpdateParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserUpdateParams.java index 7b069623e44..eda30607fbb 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserUpdateParams.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserUpdateParams.java @@ -16,23 +16,17 @@ package org.opencb.opencga.core.models.user; -import java.util.Map; - public class UserUpdateParams { private String name; private String email; - private String organization; - private Map attributes; public UserUpdateParams() { } - public UserUpdateParams(String name, String email, String organization, Map attributes) { + public UserUpdateParams(String name, String email) { this.name = name; this.email = email; - this.organization = organization; - this.attributes = attributes; } @Override @@ -40,8 +34,6 @@ public String toString() { final StringBuilder sb = new StringBuilder("UserUpdateParams{"); sb.append("name='").append(name).append('\''); sb.append(", email='").append(email).append('\''); - sb.append(", organization='").append(organization).append('\''); - sb.append(", attributes=").append(attributes); sb.append('}'); return sb.toString(); } @@ -64,21 +56,4 @@ public UserUpdateParams setEmail(String email) { return this; } - public String getOrganization() { - return organization; - } - - public UserUpdateParams setOrganization(String organization) { - this.organization = organization; - return this; - } - - public Map getAttributes() { - return attributes; - } - - public UserUpdateParams setAttributes(Map attributes) { - this.attributes = attributes; - return this; - } } diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java index 9deeb489110..d449063d7b6 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java @@ -29,6 +29,8 @@ import org.opencb.opencga.core.models.organizations.Organization; import org.opencb.opencga.core.models.organizations.OrganizationCreateParams; import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; +import org.opencb.opencga.core.models.user.OrganizationUserUpdateParams; +import org.opencb.opencga.core.models.user.User; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.tools.annotations.*; @@ -196,4 +198,26 @@ public Response deleteNote( } } + @POST + @Path("/user/{user}/update") + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update the user information", response = User.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = QueryOptions.INCLUDE, value = ParamConstants.INCLUDE_DESCRIPTION, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = QueryOptions.EXCLUDE, value = ParamConstants.EXCLUDE_DESCRIPTION, dataType = "string", paramType = "query") + }) + public Response updateUserInformation( + @ApiParam(value = ParamConstants.USER_DESCRIPTION, required = true) @PathParam("user") String userId, + @ApiParam(value = ParamConstants.ORGANIZATION_DESCRIPTION) @QueryParam(ParamConstants.ORGANIZATION) String organizationId, + @ApiParam(value = ParamConstants.INCLUDE_RESULT_DESCRIPTION, defaultValue = "false") @QueryParam(ParamConstants.INCLUDE_RESULT_PARAM) boolean includeResult, + @ApiParam(value = "JSON containing the User fields to be updated.", required = true) OrganizationUserUpdateParams parameters) { + try { + OpenCGAResult result = catalogManager.getOrganizationManager().updateUser(organizationId, userId, parameters, queryOptions, token); + return createOkResponse(result); + } catch (Exception e) { + return createErrorResponse(e); + } + } + + } \ No newline at end of file From 4b7c93553e3b308c00e4f812227c5e38ec2edb92 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 18 Apr 2024 15:33:41 +0200 Subject: [PATCH 02/20] catalog: implement ban option after several attempts, #TASK-6013 --- .../opencga/catalog/db/api/UserDBAdaptor.java | 2 + .../db/mongodb/UserMongoDBAdaptor.java | 43 ++++--- .../CatalogAuthenticationException.java | 10 ++ .../opencga/catalog/managers/UserManager.java | 111 +++++++++++++++++- .../catalog/managers/CatalogManagerTest.java | 87 +++++++++++++- .../opencb/opencga/core/common/TimeUtils.java | 8 ++ .../core/models/user/UserInternal.java | 24 +++- .../models/user/UserStatusUpdateParams.java | 30 +++++ .../server/rest/OrganizationWSServer.java | 22 ++++ 9 files changed, 304 insertions(+), 33 deletions(-) create mode 100644 opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserStatusUpdateParams.java diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java index 045e50d7f26..3099262e917 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/api/UserDBAdaptor.java @@ -118,6 +118,8 @@ enum QueryParams implements QueryParam { NAME("name", TEXT_ARRAY, ""), EMAIL("email", TEXT_ARRAY, ""), ORGANIZATION("organization", TEXT_ARRAY, ""), + INTERNAL("internal", OBJECT, ""), + INTERNAL_FAILED_ATTEMPTS("internal.failedAttempts", INTEGER, ""), INTERNAL_STATUS_ID("internal.status.id", TEXT, ""), INTERNAL_STATUS_DATE("internal.status.date", TEXT, ""), ACCOUNT("account", TEXT_ARRAY, ""), diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java index 6c08e34c536..a22ec883433 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/UserMongoDBAdaptor.java @@ -30,10 +30,7 @@ import org.opencb.commons.datastore.mongodb.MongoDBCollection; import org.opencb.commons.datastore.mongodb.MongoDBIterator; import org.opencb.commons.utils.CryptoUtils; -import org.opencb.opencga.catalog.db.api.DBIterator; -import org.opencb.opencga.catalog.db.api.ProjectDBAdaptor; -import org.opencb.opencga.catalog.db.api.StudyDBAdaptor; -import org.opencb.opencga.catalog.db.api.UserDBAdaptor; +import org.opencb.opencga.catalog.db.api.*; import org.opencb.opencga.catalog.db.mongodb.converters.UserConverter; import org.opencb.opencga.catalog.db.mongodb.iterators.CatalogMongoDBIterator; import org.opencb.opencga.catalog.exceptions.CatalogAuthenticationException; @@ -432,30 +429,36 @@ public OpenCGAResult nativeGet(Query query, QueryOptions options) throws Catalog @Override public OpenCGAResult update(Query query, ObjectMap parameters, QueryOptions queryOptions) throws CatalogDBException { - Map userParameters = new HashMap<>(); + UpdateDocument document = new UpdateDocument(); - final String[] acceptedParams = {QueryParams.NAME.key(), QueryParams.EMAIL.key(), QueryParams.ORGANIZATION.key()}; - filterStringParams(parameters, userParameters, acceptedParams); + final String[] acceptedParams = {QueryParams.NAME.key(), QueryParams.EMAIL.key(), QueryParams.ORGANIZATION.key(), + ACCOUNT_EXPIRATION_DATE.key()}; + filterStringParams(parameters, document.getSet(), acceptedParams); if (parameters.containsKey(QueryParams.INTERNAL_STATUS_ID.key())) { - userParameters.put(QueryParams.INTERNAL_STATUS_ID.key(), parameters.get(QueryParams.INTERNAL_STATUS_ID.key())); - userParameters.put(QueryParams.INTERNAL_STATUS_DATE.key(), TimeUtils.getTime()); - } - if (parameters.containsKey(ACCOUNT_EXPIRATION_DATE.key())) { - userParameters.put(ACCOUNT_EXPIRATION_DATE.key(), parameters.get(ACCOUNT_EXPIRATION_DATE.key())); + document.getSet().put(QueryParams.INTERNAL_STATUS_ID.key(), parameters.get(QueryParams.INTERNAL_STATUS_ID.key())); + document.getSet().put(QueryParams.INTERNAL_STATUS_DATE.key(), TimeUtils.getTime()); } + final String[] acceptedIntParams = {INTERNAL_FAILED_ATTEMPTS.key()}; + filterIntParams(parameters, document.getSet(), acceptedIntParams); + final String[] acceptedObjectParams = {QueryParams.QUOTA.key()}; - filterObjectParams(parameters, userParameters, acceptedObjectParams); + filterObjectParams(parameters, document.getSet(), acceptedObjectParams); final String[] acceptedMapParams = {QueryParams.ATTRIBUTES.key()}; - filterMapParams(parameters, userParameters, acceptedMapParams); + filterMapParams(parameters, document.getSet(), acceptedMapParams); - if (!userParameters.isEmpty()) { - return new OpenCGAResult(userCollection.update(parseQuery(query), new Document("$set", userParameters), null)); + if (!document.toFinalUpdateDocument().isEmpty()) { + document.getSet().put(INTERNAL_LAST_MODIFIED, TimeUtils.getTime()); } - return OpenCGAResult.empty(); + Document userUpdate = document.toFinalUpdateDocument(); + if (userUpdate.isEmpty()) { + throw new CatalogDBException("Nothing to be updated."); + } + + return new OpenCGAResult(userCollection.update(parseQuery(query), userUpdate, null)); } @Override @@ -484,11 +487,7 @@ public OpenCGAResult update(String userId, ObjectMap parameters) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { checkId(userId); Query query = new Query(QueryParams.ID.key(), userId); - OpenCGAResult update = update(query, parameters, QueryOptions.empty()); - if (update.getNumUpdated() != 1) { - throw new CatalogDBException("Could not update user " + userId); - } - return update; + return update(query, parameters, QueryOptions.empty()); } OpenCGAResult setStatus(Query query, String status) throws CatalogDBException { diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java index 8cb658885dc..3ae2ceff16b 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java @@ -61,6 +61,16 @@ public static CatalogAuthenticationException incorrectUserOrPassword(String doma return new CatalogAuthenticationException(domain + ": Incorrect user or password.", e); } + public static CatalogAuthenticationException userIsBanned(String userId) { + return new CatalogAuthenticationException("The account for user '" + userId + "' is banned. Please, talk to your organization" + + " owner/administrator."); + } + + public static CatalogAuthenticationException accountIsExpired(String userId, String expirationDate) { + return new CatalogAuthenticationException("The account for user '" + userId + "' expired on " + expirationDate + ". Please," + + " talk to your organization owner/administrator."); + } + public static CatalogAuthenticationException userNotAllowed(String domain) { return new CatalogAuthenticationException(domain + ": User not allowed to access the system."); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index b54a9fa0ef3..833e81a458e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -59,8 +59,8 @@ */ public class UserManager extends AbstractManager { - static final QueryOptions INCLUDE_ACCOUNT = new QueryOptions(QueryOptions.INCLUDE, Arrays.asList( - UserDBAdaptor.QueryParams.ID.key(), UserDBAdaptor.QueryParams.ACCOUNT.key())); + static final QueryOptions INCLUDE_ACCOUNT_AND_INTERNAL = new QueryOptions(QueryOptions.INCLUDE, Arrays.asList( + UserDBAdaptor.QueryParams.ID.key(), UserDBAdaptor.QueryParams.ACCOUNT.key(), UserDBAdaptor.QueryParams.INTERNAL.key())); protected static Logger logger = LoggerFactory.getLogger(UserManager.class); private final CatalogIOManager catalogIOManager; private final AuthenticationFactory authenticationFactory; @@ -130,7 +130,14 @@ public OpenCGAResult create(User user, String password, String token) thro } user.setAccount(ParamUtils.defaultObject(user.getAccount(), Account::new)); user.getAccount().setCreationDate(TimeUtils.getTime()); - user.getAccount().setExpirationDate(ParamUtils.defaultString(user.getAccount().getExpirationDate(), "")); + if (StringUtils.isEmpty(user.getAccount().getExpirationDate())) { + // By default, user accounts will be valid for 1 year when they are created. + Date date = TimeUtils.add1YeartoDate(new Date()); + user.getAccount().setExpirationDate(TimeUtils.getTime(date)); + } else { + // Validate expiration date is not over + ParamUtils.checkDateIsNotExpired(user.getAccount().getExpirationDate(), "account.expirationDate"); + } user.setInternal(new UserInternal(new UserStatus(UserStatus.READY))); user.setQuota(ParamUtils.defaultObject(user.getQuota(), UserQuota::new)); user.setProjects(ParamUtils.defaultObject(user.getProjects(), Collections::emptyList)); @@ -212,7 +219,7 @@ public JwtPayload validateToken(String token) throws CatalogException { if (ParamConstants.ANONYMOUS_USER_ID.equals(jwtPayload.getUserId())) { authOrigin = CatalogAuthenticationManager.INTERNAL; } else { - OpenCGAResult userResult = getUserDBAdaptor(jwtPayload.getOrganization()).get(jwtPayload.getUserId(), INCLUDE_ACCOUNT); + OpenCGAResult userResult = getUserDBAdaptor(jwtPayload.getOrganization()).get(jwtPayload.getUserId(), INCLUDE_ACCOUNT_AND_INTERNAL); if (userResult.getNumResults() == 0) { throw new CatalogException("User '" + jwtPayload.getUserId() + "' could not be found."); } @@ -737,12 +744,37 @@ public AuthenticationResponse login(String organizationId, String username, Stri } } - OpenCGAResult userOpenCGAResult = getUserDBAdaptor(organizationId).get(username, INCLUDE_ACCOUNT); + OpenCGAResult userOpenCGAResult = getUserDBAdaptor(organizationId).get(username, INCLUDE_ACCOUNT_AND_INTERNAL); if (userOpenCGAResult.getNumResults() == 1) { + User user = userOpenCGAResult.first(); + if (!ParamConstants.ADMIN_ORGANIZATION.equals(organizationId)) { + // Check user is not banned or account is expired + if (UserStatus.BANNED.equals(user.getInternal().getStatus().getId())) { + throw CatalogAuthenticationException.userIsBanned(username); + } + Date date = TimeUtils.toDate(user.getAccount().getExpirationDate()); + if (date == null) { + throw new CatalogException("Unexpected null expiration date for user '" + username + "'."); + } + if (date.before(new Date())) { + throw CatalogAuthenticationException.accountIsExpired(username, user.getAccount().getExpirationDate()); + } + } authId = userOpenCGAResult.first().getAccount().getAuthentication().getId(); try { response = authenticationFactory.authenticate(organizationId, authId, username, password); } catch (CatalogAuthenticationException e) { + if (!ParamConstants.ADMIN_ORGANIZATION.equals(organizationId)) { + // We can only lock the account if it is not the root user + int failedAttempts = userOpenCGAResult.first().getInternal().getFailedAttempts(); + ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), failedAttempts + 1); + if (failedAttempts >= 4) { + // Ban the account + updateParams.append(UserDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), UserStatus.BANNED); + } + getUserDBAdaptor(organizationId).update(username, updateParams); + } + auditManager.auditUser(organizationId, username, Enums.Action.LOGIN, username, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError())); throw e; @@ -768,6 +800,10 @@ public AuthenticationResponse login(String organizationId, String username, Stri throw CatalogAuthenticationException.incorrectUserOrPassword(); } + // Reset login failed attempts counter + ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), 0); + getUserDBAdaptor(organizationId).update(username, updateParams); + auditManager.auditUser(organizationId, username, Enums.Action.LOGIN, username, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); String userId = authenticationFactory.getUserId(organizationId, authId, response.getToken()); @@ -854,6 +890,69 @@ public AuthenticationResponse refreshToken(String token) throws CatalogException return response; } + public OpenCGAResult changeStatus(String organizationId, String userId, String status, QueryOptions options, String token) + throws CatalogException { + JwtPayload tokenPayload = validateToken(token); + String userIdOrganization = StringUtils.isNotEmpty(organizationId) ? organizationId : tokenPayload.getOrganization(); + + ObjectMap auditParams = new ObjectMap() + .append("organizationId", organizationId) + .append("userId", userId) + .append("status", status) + .append("options", options) + .append("token", token); + try { + authorizationManager.checkIsAtLeastOrganizationOwnerOrAdmin(userIdOrganization, tokenPayload.getUserId(userIdOrganization)); + options = ParamUtils.defaultObject(options, QueryOptions::new); + + // Validate user exists + getUserDBAdaptor(userIdOrganization).checkId(userId); + + // Validate status is valid + if (!UserStatus.isValid(status)) { + throw new CatalogParameterException("Invalid status '" + status + "'. Valid values are: " + UserStatus.STATUS_LIST); + } + + if (UserStatus.BANNED.equals(status)) { + // Get organization information + Set ownerAndAdmins = catalogManager.getOrganizationManager().getOrganizationOwnerAndAdmins(userIdOrganization); + if (ownerAndAdmins.contains(userId)) { + if (tokenPayload.getUserId().equals(userId)) { + // The user is trying to ban himself + throw new CatalogAuthorizationException("You can't ban your own account."); + } + if (!authorizationManager.isAtLeastOrganizationOwner(userIdOrganization, tokenPayload.getUserId(userIdOrganization))) { + // One of the admins is trying to ban the owner or one of the admins + throw new CatalogAuthorizationException("Only the owner of the organization can ban administrators."); + } + } + } + + // Update user status and reset failed attempts to 0 + ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), status); + if (!UserStatus.BANNED.equals(status)) { + updateParams.put(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), 0); + } + OpenCGAResult result = getUserDBAdaptor(userIdOrganization).update(userId, updateParams); + + auditManager.auditUpdate(organizationId, tokenPayload.getUserId(userIdOrganization), Enums.Resource.USER, userId, "", "", "", + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); + + if (options.getBoolean(ParamConstants.INCLUDE_RESULT_PARAM)) { + // Fetch updated user + OpenCGAResult tmpResult = getUserDBAdaptor(userIdOrganization).get(userId, options); + result.setResults(tmpResult.getResults()); + } + + return result; + } catch (Exception e) { + auditManager.auditUpdate(organizationId, tokenPayload.getUserId(userIdOrganization), Enums.Resource.USER, userId, "", "", "", + auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, new Error(-1, "Could not update user status", + e.getMessage()))); + throw e; + } + } + /** * This method will be only callable by the system. It generates a new session id for the user. * @@ -899,7 +998,7 @@ public String getNonExpiringToken(String organizationId, String userId, Map userOpenCGAResult = getUserDBAdaptor(organizationId).get(user, INCLUDE_ACCOUNT); + OpenCGAResult userOpenCGAResult = getUserDBAdaptor(organizationId).get(user, INCLUDE_ACCOUNT_AND_INTERNAL); if (userOpenCGAResult.getNumResults() == 1) { String authId = userOpenCGAResult.first().getAccount().getAuthentication().getId(); return authenticationFactory.getOrganizationAuthenticationManager(organizationId, authId); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index df98ce12de5..4b3d8cc9c91 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -57,10 +57,7 @@ import org.opencb.opencga.core.models.project.ProjectOrganism; import org.opencb.opencga.core.models.sample.*; import org.opencb.opencga.core.models.study.*; -import org.opencb.opencga.core.models.user.Account; -import org.opencb.opencga.core.models.user.AuthenticationResponse; -import org.opencb.opencga.core.models.user.User; -import org.opencb.opencga.core.models.user.UserUpdateParams; +import org.opencb.opencga.core.models.user.*; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.testclassification.duration.MediumTests; @@ -227,6 +224,88 @@ public void anonymousUserLoginTest() throws CatalogException { catalogManager.getUserManager().loginAnonymous(org2); } + @Test + public void incrementLoginAttemptsTest() throws CatalogException { + assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, normalUserId1, "incorrect")); + User user = catalogManager.getUserManager().get(organizationId, normalUserId1, QueryOptions.empty(), ownerToken).first(); + assertEquals(1, user.getInternal().getFailedAttempts()); + assertEquals(UserStatus.READY, user.getInternal().getStatus().getId()); + + for (int i = 2; i < 5; i++) { + assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, normalUserId1, "incorrect")); + user = catalogManager.getUserManager().get(organizationId, normalUserId1, QueryOptions.empty(), ownerToken).first(); + assertEquals(i, user.getInternal().getFailedAttempts()); + assertEquals(UserStatus.READY, user.getInternal().getStatus().getId()); + } + + assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, normalUserId1, "incorrect")); + user = catalogManager.getUserManager().get(organizationId, normalUserId1, QueryOptions.empty(), ownerToken).first(); + assertEquals(5, user.getInternal().getFailedAttempts()); + assertEquals(UserStatus.BANNED, user.getInternal().getStatus().getId()); + + CatalogAuthenticationException incorrect = assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, normalUserId1, "incorrect")); + assertTrue(incorrect.getMessage().contains("banned")); + user = catalogManager.getUserManager().get(organizationId, normalUserId1, QueryOptions.empty(), ownerToken).first(); + assertEquals(5, user.getInternal().getFailedAttempts()); + assertEquals(UserStatus.BANNED, user.getInternal().getStatus().getId()); + + CatalogAuthenticationException authException = assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, normalUserId1, TestParamConstants.PASSWORD)); + assertTrue(authException.getMessage().contains("banned")); + + // Remove ban from user + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.READY, ownerToken); + user = catalogManager.getUserManager().get(organizationId, normalUserId1, QueryOptions.empty(), ownerToken).first(); + assertEquals(0, user.getInternal().getFailedAttempts()); + assertEquals(UserStatus.READY, user.getInternal().getStatus().getId()); + + String token = catalogManager.getUserManager().login(organizationId, normalUserId1, TestParamConstants.PASSWORD).getToken(); + assertNotNull(token); + } + + @Test + public void changeUserStatusTest() throws CatalogException { + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, normalToken1)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, studyAdminToken1)); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, ownerToken); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, orgAdminToken1); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, opencgaToken); + + catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, ownerToken); + CatalogAuthorizationException authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgOwnerUserId, UserStatus.BANNED, ownerToken)); + assertTrue(authException.getMessage().contains("own account")); + + authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, orgAdminToken2)); + assertTrue(authException.getMessage().contains("ban administrators")); + + CatalogAuthenticationException incorrect = assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, orgAdminUserId1, TestParamConstants.PASSWORD)); + assertTrue(incorrect.getMessage().contains("banned")); + + catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.READY, orgAdminToken2); + String token = catalogManager.getUserManager().login(organizationId, orgAdminUserId1, TestParamConstants.PASSWORD).getToken(); + assertNotNull(token); + + CatalogParameterException paramException = assertThrows(CatalogParameterException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, "NOT_A_STATUS", orgAdminToken2)); + assertTrue(paramException.getMessage().contains("Invalid status")); + + CatalogDBException dbException = assertThrows(CatalogDBException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, "notAUser", UserStatus.BANNED, orgAdminToken2)); + assertTrue(dbException.getMessage().contains("not exist")); + } + + @Test + public void loginExpiredAccountTest() throws CatalogException { + // Expire account of normalUserId1 + ObjectMap params = new ObjectMap(UserDBAdaptor.QueryParams.ACCOUNT_EXPIRATION_DATE.key(), TimeUtils.getTime()); + catalogManager.getUserManager().getUserDBAdaptor(organizationId).update(normalUserId1, params); + + CatalogAuthenticationException authException = assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, normalUserId1, TestParamConstants.PASSWORD)); + assertTrue(authException.getMessage().contains("expired")); + + // Ensure it doesn't matter whether opencga account is expired or not + catalogManager.getUserManager().getUserDBAdaptor(ParamConstants.ADMIN_ORGANIZATION).update(ParamConstants.OPENCGA_USER_ID, params); + String token = catalogManager.getUserManager().login(ParamConstants.ADMIN_ORGANIZATION, ParamConstants.OPENCGA_USER_ID, TestParamConstants.ADMIN_PASSWORD).getToken(); + assertNotNull(token); + } + @Test public void updateUserTest() throws JsonProcessingException, CatalogException { UserUpdateParams userUpdateParams = new UserUpdateParams() diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/TimeUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/TimeUtils.java index 65c2cfda80b..da6aa39f1f6 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/TimeUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/TimeUtils.java @@ -127,6 +127,14 @@ public static Date add1MonthtoDate(Date date) { return new Date(cal.getTimeInMillis()); } + public static Date add1YeartoDate(Date date) { + Calendar cal = new GregorianCalendar(); + cal.setTime(date); + cal.setTimeInMillis(date.getTime()); + cal.add(Calendar.YEAR, 1); + return new Date(cal.getTimeInMillis()); + } + public static Date toDate(String dateStr) { Date date = null; try { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserInternal.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserInternal.java index 9a4b5fc9e23..329db613b5b 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserInternal.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserInternal.java @@ -16,21 +16,34 @@ package org.opencb.opencga.core.models.user; -public class UserInternal { +import org.opencb.opencga.core.common.TimeUtils; +import org.opencb.opencga.core.models.common.Internal; + +public class UserInternal extends Internal { private UserStatus status; + private int failedAttempts; public UserInternal() { } public UserInternal(UserStatus status) { + this(TimeUtils.getTime(), TimeUtils.getTime(), status); + } + + public UserInternal(String registrationDate, String lastModified, UserStatus status) { + super(null, registrationDate, lastModified); this.status = status; + this.failedAttempts = 0; } @Override public String toString() { final StringBuilder sb = new StringBuilder("UserInternal{"); sb.append("status=").append(status); + sb.append(", failedAttempts=").append(failedAttempts); + sb.append(", registrationDate='").append(registrationDate).append('\''); + sb.append(", lastModified='").append(lastModified).append('\''); sb.append('}'); return sb.toString(); } @@ -43,4 +56,13 @@ public UserInternal setStatus(UserStatus status) { this.status = status; return this; } + + public int getFailedAttempts() { + return failedAttempts; + } + + public UserInternal setFailedAttempts(int failedAttempts) { + this.failedAttempts = failedAttempts; + return this; + } } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserStatusUpdateParams.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserStatusUpdateParams.java new file mode 100644 index 00000000000..5c0356ded8e --- /dev/null +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/user/UserStatusUpdateParams.java @@ -0,0 +1,30 @@ +package org.opencb.opencga.core.models.user; + +public class UserStatusUpdateParams { + + private String status; + + public UserStatusUpdateParams() { + } + + public UserStatusUpdateParams(String status) { + this.status = status; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("UserStatusUpdateParams{"); + sb.append("status='").append(status).append('\''); + sb.append('}'); + return sb.toString(); + } + + public String getStatus() { + return status; + } + + public UserStatusUpdateParams setStatus(String status) { + this.status = status; + return this; + } +} diff --git a/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java b/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java index d449063d7b6..e1ae6488108 100644 --- a/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java +++ b/opencga-server/src/main/java/org/opencb/opencga/server/rest/OrganizationWSServer.java @@ -31,6 +31,7 @@ import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; import org.opencb.opencga.core.models.user.OrganizationUserUpdateParams; import org.opencb.opencga.core.models.user.User; +import org.opencb.opencga.core.models.user.UserStatusUpdateParams; import org.opencb.opencga.core.response.OpenCGAResult; import org.opencb.opencga.core.tools.annotations.*; @@ -219,5 +220,26 @@ public Response updateUserInformation( } } + @POST + @Path("/user/{user}/status/update") + @Consumes(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update the user status", response = User.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = QueryOptions.INCLUDE, value = ParamConstants.INCLUDE_DESCRIPTION, dataType = "string", paramType = "query"), + @ApiImplicitParam(name = QueryOptions.EXCLUDE, value = ParamConstants.EXCLUDE_DESCRIPTION, dataType = "string", paramType = "query") + }) + public Response updateUserStatus( + @ApiParam(value = ParamConstants.USER_DESCRIPTION, required = true) @PathParam("user") String userId, + @ApiParam(value = ParamConstants.ORGANIZATION_DESCRIPTION) @QueryParam(ParamConstants.ORGANIZATION) String organizationId, + @ApiParam(value = ParamConstants.INCLUDE_RESULT_DESCRIPTION, defaultValue = "false") @QueryParam(ParamConstants.INCLUDE_RESULT_PARAM) boolean includeResult, + @ApiParam(value = "JSON containing the User fields to be updated.", required = true) UserStatusUpdateParams parameters) { + try { + OpenCGAResult result = catalogManager.getUserManager().changeStatus(organizationId, userId, parameters.getStatus(), queryOptions, token); + return createOkResponse(result); + } catch (Exception e) { + return createErrorResponse(e); + } + } + } \ No newline at end of file From 3da2c678532630ed2918f3726b3640cfb9949b9d Mon Sep 17 00:00:00 2001 From: pfurio Date: Fri, 19 Apr 2024 12:53:44 +0200 Subject: [PATCH 03/20] app: add migration script, #TASK-6013 --- .../migrations/v3_1_0/UserBanMigration.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java new file mode 100644 index 00000000000..57c8b52a47f --- /dev/null +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java @@ -0,0 +1,43 @@ +package org.opencb.opencga.app.migrations.v3_1_0; + +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Projections; +import com.mongodb.client.model.UpdateOneModel; +import com.mongodb.client.model.Updates; +import org.bson.Document; +import org.opencb.opencga.catalog.db.mongodb.OrganizationMongoDBAdaptorFactory; +import org.opencb.opencga.catalog.migration.Migration; +import org.opencb.opencga.catalog.migration.MigrationTool; +import org.opencb.opencga.core.common.TimeUtils; + +import java.util.Date; + +@Migration(id = "addFailedLoginAttemtsMigration", description = "Add failedAttempts to User #TASK-6013", version = "3.1.0", + language = Migration.MigrationLanguage.JAVA, domain = Migration.MigrationDomain.CATALOG, date = 20240419) +public class UserBanMigration extends MigrationTool { + + @Override + protected void run() throws Exception { + String lastModified = TimeUtils.getTime(); + String expirationDate = TimeUtils.getTime(TimeUtils.add1YeartoDate(new Date())); + migrateCollection(OrganizationMongoDBAdaptorFactory.USER_COLLECTION, + Filters.exists("internal.failedAttempts", false), + Projections.include("_id", "internal", "account"), + (document, bulk) -> { + Document internal = document.get("internal", Document.class); + Document account = document.get("account", Document.class); + internal.put("failedAttempts", 0); + internal.put("registrationDate", account.get("creationDate")); + internal.put("lastModified", lastModified); + account.put("expirationDate", expirationDate); + + bulk.add(new UpdateOneModel<>(Filters.eq("_id", document.get("_id")), + Updates.combine( + Updates.set("internal", internal), + Updates.set("account", account)) + ) + ); + }); + } + +} From af2bb26339c7543d36ecd71c0848c4550d929d9d Mon Sep 17 00:00:00 2001 From: pfurio Date: Fri, 19 Apr 2024 13:03:53 +0200 Subject: [PATCH 04/20] catalog: fix compilation issues, #TASK-6013 --- .../opencga/catalog/managers/UserManager.java | 3 +- .../catalog/managers/CatalogManagerTest.java | 28 +++++++++---------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index 833e81a458e..f07a81a4a27 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -219,7 +219,8 @@ public JwtPayload validateToken(String token) throws CatalogException { if (ParamConstants.ANONYMOUS_USER_ID.equals(jwtPayload.getUserId())) { authOrigin = CatalogAuthenticationManager.INTERNAL; } else { - OpenCGAResult userResult = getUserDBAdaptor(jwtPayload.getOrganization()).get(jwtPayload.getUserId(), INCLUDE_ACCOUNT_AND_INTERNAL); + OpenCGAResult userResult = getUserDBAdaptor(jwtPayload.getOrganization()).get(jwtPayload.getUserId(), + INCLUDE_ACCOUNT_AND_INTERNAL); if (userResult.getNumResults() == 0) { throw new CatalogException("User '" + jwtPayload.getUserId() + "' could not be found."); } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index 4b3d8cc9c91..5390bb55276 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -253,7 +253,7 @@ public void incrementLoginAttemptsTest() throws CatalogException { assertTrue(authException.getMessage().contains("banned")); // Remove ban from user - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.READY, ownerToken); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.READY, QueryOptions.empty(), ownerToken); user = catalogManager.getUserManager().get(organizationId, normalUserId1, QueryOptions.empty(), ownerToken).first(); assertEquals(0, user.getInternal().getFailedAttempts()); assertEquals(UserStatus.READY, user.getInternal().getStatus().getId()); @@ -264,30 +264,30 @@ public void incrementLoginAttemptsTest() throws CatalogException { @Test public void changeUserStatusTest() throws CatalogException { - assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, normalToken1)); - assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, studyAdminToken1)); - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, ownerToken); - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, orgAdminToken1); - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, opencgaToken); - - catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, ownerToken); - CatalogAuthorizationException authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgOwnerUserId, UserStatus.BANNED, ownerToken)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), normalToken1)); + assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), studyAdminToken1)); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), ownerToken); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), orgAdminToken1); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), opencgaToken); + + catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, QueryOptions.empty(), ownerToken); + CatalogAuthorizationException authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgOwnerUserId, UserStatus.BANNED, QueryOptions.empty(), ownerToken)); assertTrue(authException.getMessage().contains("own account")); - authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, orgAdminToken2)); + authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, QueryOptions.empty(), orgAdminToken2)); assertTrue(authException.getMessage().contains("ban administrators")); CatalogAuthenticationException incorrect = assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, orgAdminUserId1, TestParamConstants.PASSWORD)); assertTrue(incorrect.getMessage().contains("banned")); - catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.READY, orgAdminToken2); + catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.READY, QueryOptions.empty(), orgAdminToken2); String token = catalogManager.getUserManager().login(organizationId, orgAdminUserId1, TestParamConstants.PASSWORD).getToken(); assertNotNull(token); - CatalogParameterException paramException = assertThrows(CatalogParameterException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, "NOT_A_STATUS", orgAdminToken2)); + CatalogParameterException paramException = assertThrows(CatalogParameterException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, "NOT_A_STATUS", QueryOptions.empty(), orgAdminToken2)); assertTrue(paramException.getMessage().contains("Invalid status")); - CatalogDBException dbException = assertThrows(CatalogDBException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, "notAUser", UserStatus.BANNED, orgAdminToken2)); + CatalogDBException dbException = assertThrows(CatalogDBException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, "notAUser", UserStatus.BANNED, QueryOptions.empty(), orgAdminToken2)); assertTrue(dbException.getMessage().contains("not exist")); } @@ -361,7 +361,7 @@ public void testGetUserInfo() throws CatalogException { } @Test - public void testModifyUser() throws CatalogException, InterruptedException, IOException { + public void testModifyUser() throws CatalogException, InterruptedException { ObjectMap params = new ObjectMap(); String newName = "Changed Name " + RandomStringUtils.randomAlphanumeric(10); String newPassword = RandomStringUtils.randomAlphanumeric(10); From 8d3fcc0e03ee81978340e494f4be9820f67e8661 Mon Sep 17 00:00:00 2001 From: pfurio Date: Fri, 19 Apr 2024 13:12:41 +0200 Subject: [PATCH 05/20] app: fix target migration version, #TASK-6013 --- .../opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java index 57c8b52a47f..3ac52dbe39d 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java @@ -12,7 +12,7 @@ import java.util.Date; -@Migration(id = "addFailedLoginAttemtsMigration", description = "Add failedAttempts to User #TASK-6013", version = "3.1.0", +@Migration(id = "addFailedLoginAttemtsMigration", description = "Add failedAttempts to User #TASK-6013", version = "3.2.0", language = Migration.MigrationLanguage.JAVA, domain = Migration.MigrationDomain.CATALOG, date = 20240419) public class UserBanMigration extends MigrationTool { From 49987a62ca2f6c7ab05491b41f48572ed73f3325 Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 23 Apr 2024 11:15:46 +0200 Subject: [PATCH 06/20] catalog: fix default expirationDate, #TASK-6013 --- .../migrations/v3_1_0/UserBanMigration.java | 6 ++-- .../mongodb/OrganizationMongoDBAdaptor.java | 3 -- .../CatalogAuthenticationException.java | 7 +++- .../catalog/managers/CatalogManager.java | 3 +- .../catalog/managers/OrganizationManager.java | 3 ++ .../opencga/catalog/managers/UserManager.java | 33 ++++++++++++------- .../opencga/catalog/utils/Constants.java | 2 ++ .../catalog/managers/CatalogManagerTest.java | 28 ++++++---------- .../managers/OrganizationManagerTest.java | 8 ++--- .../OrganizationConfiguration.java | 16 +++++++-- .../opencga/core/models/user/UserStatus.java | 5 +-- 11 files changed, 68 insertions(+), 46 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java index 3ac52dbe39d..c5507012538 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java @@ -8,10 +8,9 @@ import org.opencb.opencga.catalog.db.mongodb.OrganizationMongoDBAdaptorFactory; import org.opencb.opencga.catalog.migration.Migration; import org.opencb.opencga.catalog.migration.MigrationTool; +import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.core.common.TimeUtils; -import java.util.Date; - @Migration(id = "addFailedLoginAttemtsMigration", description = "Add failedAttempts to User #TASK-6013", version = "3.2.0", language = Migration.MigrationLanguage.JAVA, domain = Migration.MigrationDomain.CATALOG, date = 20240419) public class UserBanMigration extends MigrationTool { @@ -19,7 +18,6 @@ public class UserBanMigration extends MigrationTool { @Override protected void run() throws Exception { String lastModified = TimeUtils.getTime(); - String expirationDate = TimeUtils.getTime(TimeUtils.add1YeartoDate(new Date())); migrateCollection(OrganizationMongoDBAdaptorFactory.USER_COLLECTION, Filters.exists("internal.failedAttempts", false), Projections.include("_id", "internal", "account"), @@ -29,7 +27,7 @@ protected void run() throws Exception { internal.put("failedAttempts", 0); internal.put("registrationDate", account.get("creationDate")); internal.put("lastModified", lastModified); - account.put("expirationDate", expirationDate); + account.put("expirationDate", Constants.DEFAULT_USER_EXPIRATION_DATE); bulk.add(new UpdateOneModel<>(Filters.eq("_id", document.get("_id")), Updates.combine( diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/OrganizationMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/OrganizationMongoDBAdaptor.java index 4261a247c79..c4fbacc9b01 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/OrganizationMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/OrganizationMongoDBAdaptor.java @@ -336,9 +336,6 @@ private MongoDBIterator getMongoCursor(ClientSession clientSession, Qu } qOptions = filterQueryOptionsToIncludeKeys(qOptions, OrganizationManager.INCLUDE_ORGANIZATION_IDS.getAsStringList(QueryOptions.INCLUDE)); - if (!qOptions.getBoolean(IS_ORGANIZATION_ADMIN_OPTION)) { - qOptions = filterQueryOptionsToExcludeKeys(qOptions, Arrays.asList(QueryParams.CONFIGURATION.key())); - } return organizationCollection.iterator(clientSession, new Document(), null, null, qOptions); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java index 3ae2ceff16b..3853e91607f 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/exceptions/CatalogAuthenticationException.java @@ -62,7 +62,12 @@ public static CatalogAuthenticationException incorrectUserOrPassword(String doma } public static CatalogAuthenticationException userIsBanned(String userId) { - return new CatalogAuthenticationException("The account for user '" + userId + "' is banned. Please, talk to your organization" + return new CatalogAuthenticationException("Too many login attempts. The account for user '" + userId + "' is banned." + + " Please, talk to your organization owner/administrator."); + } + + public static CatalogAuthenticationException userIsSuspended(String userId) { + return new CatalogAuthenticationException("The account for user '" + userId + "' is suspended. Please, talk to your organization" + " owner/administrator."); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java index 2308b7ad123..dd0e97eaf13 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java @@ -35,6 +35,7 @@ import org.opencb.opencga.catalog.io.CatalogIOManager; import org.opencb.opencga.catalog.io.IOManagerFactory; import org.opencb.opencga.catalog.migration.MigrationManager; +import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.JwtUtils; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.core.common.PasswordUtils; @@ -267,7 +268,7 @@ private void privateInstall(String algorithm, String secretKey, String password, OrganizationConfiguration organizationConfiguration = new OrganizationConfiguration( Collections.singletonList(CatalogAuthenticationManager.createOpencgaAuthenticationOrigin()), - new Optimizations(), new TokenConfiguration(algorithm, secretKey, 3600L)); + Constants.DEFAULT_USER_EXPIRATION_DATE, new Optimizations(), new TokenConfiguration(algorithm, secretKey, 3600L)); organizationManager.create(new OrganizationCreateParams(ADMIN_ORGANIZATION, ADMIN_ORGANIZATION, null, null, organizationConfiguration, null), QueryOptions.empty(), null); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java index 1e837e745e4..f7e096df5c2 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java @@ -17,6 +17,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogIOException; import org.opencb.opencga.catalog.exceptions.CatalogParameterException; import org.opencb.opencga.catalog.io.CatalogIOManager; +import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.catalog.utils.UuidUtils; import org.opencb.opencga.core.api.ParamConstants; @@ -406,6 +407,8 @@ private void validateOrganizationForCreation(Organization organization, String u || StringUtils.isEmpty(organization.getConfiguration().getToken().getSecretKey())) { organization.getConfiguration().setToken(TokenConfiguration.init()); } + organization.getConfiguration().setDefaultUserExpirationDate(ParamUtils.defaultString( + organization.getConfiguration().getDefaultUserExpirationDate(), Constants.DEFAULT_USER_EXPIRATION_DATE)); organization.setAttributes(ParamUtils.defaultObject(organization.getAttributes(), HashMap::new)); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index 99b9113bf70..1618bd0e70a 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -40,6 +40,7 @@ import org.opencb.opencga.core.models.JwtPayload; import org.opencb.opencga.core.models.audit.AuditRecord; import org.opencb.opencga.core.models.common.Enums; +import org.opencb.opencga.core.models.organizations.Organization; import org.opencb.opencga.core.models.study.Group; import org.opencb.opencga.core.models.study.GroupUpdateParams; import org.opencb.opencga.core.models.user.*; @@ -118,6 +119,9 @@ public OpenCGAResult create(User user, String password, String token) thro throw new CatalogException("Creating '" + OPENCGA + "' user is forbidden in any organization."); } + Organization organization = getOrganizationDBAdaptor(organizationId).get(OrganizationManager.INCLUDE_ORGANIZATION_CONFIGURATION) + .first(); + ObjectMap auditParams = new ObjectMap("user", user); // Initialise fields @@ -132,6 +136,7 @@ public OpenCGAResult create(User user, String password, String token) thro user.getAccount().setCreationDate(TimeUtils.getTime()); if (StringUtils.isEmpty(user.getAccount().getExpirationDate())) { // By default, user accounts will be valid for 1 year when they are created. + user.getAccount().setExpirationDate(organization.getConfiguration().getDefaultUserExpirationDate()); Date date = TimeUtils.add1YeartoDate(new Date()); user.getAccount().setExpirationDate(TimeUtils.getTime(date)); } else { @@ -706,7 +711,7 @@ public OpenCGAResult resetPassword(String userId, String token) throws CatalogEx JwtPayload jwtPayload = validateToken(token); String organizationId = jwtPayload.getOrganization(); try { - authorizationManager.checkIsOpencgaAdministrator(jwtPayload, "reset password"); + authorizationManager.checkIsAtLeastOrganizationOwnerOrAdmin(organizationId, jwtPayload.getUserId()); String authOrigin = getAuthenticationOriginId(organizationId, userId); OpenCGAResult writeResult = authenticationFactory.resetPassword(organizationId, authOrigin, userId); @@ -748,8 +753,10 @@ public AuthenticationResponse login(String organizationId, String username, Stri OpenCGAResult userOpenCGAResult = getUserDBAdaptor(organizationId).get(username, INCLUDE_ACCOUNT_AND_INTERNAL); if (userOpenCGAResult.getNumResults() == 1) { User user = userOpenCGAResult.first(); - if (!ParamConstants.ADMIN_ORGANIZATION.equals(organizationId)) { - // Check user is not banned or account is expired + // We check + if (!ParamConstants.ADMIN_ORGANIZATION.equals(organizationId) + && CatalogAuthenticationManager.OPENCGA.equals(user.getAccount().getAuthentication().getId())) { + // Check user is not banned, suspended or has an expired account if (UserStatus.BANNED.equals(user.getInternal().getStatus().getId())) { throw CatalogAuthenticationException.userIsBanned(username); } @@ -761,6 +768,9 @@ public AuthenticationResponse login(String organizationId, String username, Stri throw CatalogAuthenticationException.accountIsExpired(username, user.getAccount().getExpirationDate()); } } + if (UserStatus.SUSPENDED.equals(user.getInternal().getStatus().getId())) { + throw CatalogAuthenticationException.userIsSuspended(username); + } authId = userOpenCGAResult.first().getAccount().getAuthentication().getId(); try { response = authenticationFactory.authenticate(organizationId, authId, username, password); @@ -910,28 +920,29 @@ public OpenCGAResult changeStatus(String organizationId, String userId, St getUserDBAdaptor(userIdOrganization).checkId(userId); // Validate status is valid - if (!UserStatus.isValid(status)) { - throw new CatalogParameterException("Invalid status '" + status + "'. Valid values are: " + UserStatus.STATUS_LIST); + if (!UserStatus.READY.equals(status) && !UserStatus.SUSPENDED.equals(status)) { + throw new CatalogParameterException("Invalid status '" + status + "'. Valid values are: " + UserStatus.READY + ", " + + UserStatus.SUSPENDED); } - if (UserStatus.BANNED.equals(status)) { + if (UserStatus.SUSPENDED.equals(status)) { // Get organization information Set ownerAndAdmins = catalogManager.getOrganizationManager().getOrganizationOwnerAndAdmins(userIdOrganization); if (ownerAndAdmins.contains(userId)) { if (tokenPayload.getUserId().equals(userId)) { - // The user is trying to ban himself - throw new CatalogAuthorizationException("You can't ban your own account."); + // The user is trying to suspend himself + throw new CatalogAuthorizationException("You can't suspend your own account."); } if (!authorizationManager.isAtLeastOrganizationOwner(userIdOrganization, tokenPayload.getUserId(userIdOrganization))) { - // One of the admins is trying to ban the owner or one of the admins - throw new CatalogAuthorizationException("Only the owner of the organization can ban administrators."); + // One of the admins is trying to suspend the owner or one of the admins + throw new CatalogAuthorizationException("Only the owner of the organization can suspend administrators."); } } } // Update user status and reset failed attempts to 0 ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), status); - if (!UserStatus.BANNED.equals(status)) { + if (UserStatus.READY.equals(status)) { updateParams.put(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), 0); } OpenCGAResult result = getUserDBAdaptor(userIdOrganization).update(userId, updateParams); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java index 543502a6f87..8b1f4ac747e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java @@ -111,4 +111,6 @@ public class Constants { */ public static final String JOB_DELETED_OUTPUT_DIRECTORY = "deletedOutputFiles"; + public static final String DEFAULT_USER_EXPIRATION_DATE = "21000101000000"; + } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index 38f2d6ca91c..43284db76dd 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -17,7 +17,6 @@ package org.opencb.opencga.catalog.managers; import com.fasterxml.jackson.core.JsonProcessingException; -import com.mongodb.BasicDBObject; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.junit.Ignore; @@ -266,19 +265,20 @@ public void incrementLoginAttemptsTest() throws CatalogException { public void changeUserStatusTest() throws CatalogException { assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), normalToken1)); assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), studyAdminToken1)); - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), ownerToken); - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), orgAdminToken1); - catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), opencgaToken); + assertThrows(CatalogParameterException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.BANNED, QueryOptions.empty(), ownerToken)); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.SUSPENDED, QueryOptions.empty(), ownerToken); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.SUSPENDED, QueryOptions.empty(), orgAdminToken1); + catalogManager.getUserManager().changeStatus(organizationId, normalUserId1, UserStatus.SUSPENDED, QueryOptions.empty(), opencgaToken); - catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, QueryOptions.empty(), ownerToken); - CatalogAuthorizationException authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgOwnerUserId, UserStatus.BANNED, QueryOptions.empty(), ownerToken)); + catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.SUSPENDED, QueryOptions.empty(), ownerToken); + CatalogAuthorizationException authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgOwnerUserId, UserStatus.SUSPENDED, QueryOptions.empty(), ownerToken)); assertTrue(authException.getMessage().contains("own account")); - authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.BANNED, QueryOptions.empty(), orgAdminToken2)); - assertTrue(authException.getMessage().contains("ban administrators")); + authException = assertThrows(CatalogAuthorizationException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.SUSPENDED, QueryOptions.empty(), orgAdminToken2)); + assertTrue(authException.getMessage().contains("suspend administrators")); CatalogAuthenticationException incorrect = assertThrows(CatalogAuthenticationException.class, () -> catalogManager.getUserManager().login(organizationId, orgAdminUserId1, TestParamConstants.PASSWORD)); - assertTrue(incorrect.getMessage().contains("banned")); + assertTrue(incorrect.getMessage().contains("suspended")); catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, UserStatus.READY, QueryOptions.empty(), orgAdminToken2); String token = catalogManager.getUserManager().login(organizationId, orgAdminUserId1, TestParamConstants.PASSWORD).getToken(); @@ -287,7 +287,7 @@ public void changeUserStatusTest() throws CatalogException { CatalogParameterException paramException = assertThrows(CatalogParameterException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, orgAdminUserId1, "NOT_A_STATUS", QueryOptions.empty(), orgAdminToken2)); assertTrue(paramException.getMessage().contains("Invalid status")); - CatalogDBException dbException = assertThrows(CatalogDBException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, "notAUser", UserStatus.BANNED, QueryOptions.empty(), orgAdminToken2)); + CatalogDBException dbException = assertThrows(CatalogDBException.class, () -> catalogManager.getUserManager().changeStatus(organizationId, "notAUser", UserStatus.SUSPENDED, QueryOptions.empty(), orgAdminToken2)); assertTrue(dbException.getMessage().contains("not exist")); } @@ -368,10 +368,6 @@ public void testModifyUser() throws CatalogException, InterruptedException { String newEmail = "new@email.ac.uk"; params.put("name", newName); - ObjectMap attributes = new ObjectMap("myBoolean", true); - attributes.put("value", 6); - attributes.put("object", new BasicDBObject("id", 1234)); - params.put("attributes", attributes); Thread.sleep(10); @@ -388,10 +384,6 @@ public void testModifyUser() throws CatalogException, InterruptedException { assertEquals(userPost.getEmail(), newEmail); catalogManager.getUserManager().login(organizationId, orgOwnerUserId, newPassword); - for (Map.Entry entry : attributes.entrySet()) { - assertEquals(userPost.getAttributes().get(entry.getKey()), entry.getValue()); - } - catalogManager.getUserManager().changePassword(organizationId, orgOwnerUserId, newPassword, TestParamConstants.PASSWORD); catalogManager.getUserManager().login(organizationId, orgOwnerUserId, TestParamConstants.PASSWORD); diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java index 4073dbb5256..c2b9550134c 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java @@ -43,7 +43,7 @@ public void ensureAuthOriginExistsTest() throws CatalogException { @Test public void ensureAuthOriginCannotBeRemovedTest() throws CatalogException { OrganizationUpdateParams updateParams = new OrganizationUpdateParams().setConfiguration(new OrganizationConfiguration( - Collections.emptyList(), null, new TokenConfiguration())); + Collections.emptyList(), Constants.DEFAULT_USER_EXPIRATION_DATE, null, new TokenConfiguration())); thrown.expect(CatalogException.class); thrown.expectMessage("OPENCGA"); catalogManager.getOrganizationManager().update(organizationId, updateParams, INCLUDE_RESULT, ownerToken); @@ -54,7 +54,7 @@ public void avoidDuplicatedOPENCGAAuthOriginTest() throws CatalogException { AuthenticationOrigin authOrigin = CatalogAuthenticationManager.createOpencgaAuthenticationOrigin(); AuthenticationOrigin authOrigin2 = CatalogAuthenticationManager.createOpencgaAuthenticationOrigin(); OrganizationUpdateParams updateParams = new OrganizationUpdateParams().setConfiguration(new OrganizationConfiguration( - Arrays.asList(authOrigin, authOrigin2), null, new TokenConfiguration())); + Arrays.asList(authOrigin, authOrigin2), Constants.DEFAULT_USER_EXPIRATION_DATE, null, new TokenConfiguration())); thrown.expect(CatalogException.class); thrown.expectMessage("OPENCGA"); @@ -67,7 +67,7 @@ public void avoidDuplicatedAuthOriginIdTest() throws CatalogException { AuthenticationOrigin authOrigin2 = CatalogAuthenticationManager.createOpencgaAuthenticationOrigin(); authOrigin2.setType(AuthenticationOrigin.AuthenticationType.LDAP); OrganizationUpdateParams updateParams = new OrganizationUpdateParams().setConfiguration(new OrganizationConfiguration( - Arrays.asList(authOrigin, authOrigin2), null, new TokenConfiguration())); + Arrays.asList(authOrigin, authOrigin2), Constants.DEFAULT_USER_EXPIRATION_DATE, null, new TokenConfiguration())); thrown.expect(CatalogException.class); thrown.expectMessage("origin id"); @@ -78,7 +78,7 @@ public void avoidDuplicatedAuthOriginIdTest() throws CatalogException { public void updateAuthOriginTest() throws CatalogException { AuthenticationOrigin authOrigin = CatalogAuthenticationManager.createOpencgaAuthenticationOrigin(); OrganizationUpdateParams updateParams = new OrganizationUpdateParams().setConfiguration(new OrganizationConfiguration( - Collections.singletonList(authOrigin), null, new TokenConfiguration())); + Collections.singletonList(authOrigin), Constants.DEFAULT_USER_EXPIRATION_DATE, null, new TokenConfiguration())); Organization organization = catalogManager.getOrganizationManager().update(organizationId, updateParams, INCLUDE_RESULT, ownerToken).first(); assertEquals(authOrigin.getId(), organization.getConfiguration().getAuthenticationOrigins().get(0).getId()); diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/models/organizations/OrganizationConfiguration.java b/opencga-core/src/main/java/org/opencb/opencga/core/models/organizations/OrganizationConfiguration.java index c8f3e849c89..cda477b2acc 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/models/organizations/OrganizationConfiguration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/models/organizations/OrganizationConfiguration.java @@ -8,15 +8,17 @@ public class OrganizationConfiguration { private List authenticationOrigins; + private String defaultUserExpirationDate; private Optimizations optimizations; private TokenConfiguration token; public OrganizationConfiguration() { } - public OrganizationConfiguration(List authenticationOrigins, Optimizations optimizations, - TokenConfiguration token) { + public OrganizationConfiguration(List authenticationOrigins, String defaultUserExpirationDate, + Optimizations optimizations, TokenConfiguration token) { this.authenticationOrigins = authenticationOrigins; + this.defaultUserExpirationDate = defaultUserExpirationDate; this.optimizations = optimizations; this.token = token; } @@ -25,6 +27,7 @@ public OrganizationConfiguration(List authenticationOrigin public String toString() { final StringBuilder sb = new StringBuilder("OrganizationConfiguration{"); sb.append("authenticationOrigins=").append(authenticationOrigins); + sb.append(", defaultUserExpirationDate='").append(defaultUserExpirationDate).append('\''); sb.append(", optimizations=").append(optimizations); sb.append(", token=").append(token); sb.append('}'); @@ -40,6 +43,15 @@ public OrganizationConfiguration setAuthenticationOrigins(List STATUS_LIST = Arrays.asList(READY, DELETED, BANNED); + public static final List STATUS_LIST = Arrays.asList(READY, DELETED, BANNED, SUSPENDED); public UserStatus(String status, String message) { if (isValid(status)) { @@ -47,7 +48,7 @@ public static boolean isValid(String status) { if (InternalStatus.isValid(status)) { return true; } - if (status != null && (status.equals(BANNED))) { + if (status != null && (status.equals(BANNED) || status.equals(SUSPENDED))) { return true; } return false; From 216628d502d7eb934f21688ce248aaf5aa7433ed Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 23 Apr 2024 11:21:30 +0200 Subject: [PATCH 07/20] catalog: add a variable with the max. login attempts, #TASK-6013 --- .../java/org/opencb/opencga/catalog/managers/UserManager.java | 3 ++- .../main/java/org/opencb/opencga/catalog/utils/Constants.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index 5f3052f20d2..391fc05c040 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -31,6 +31,7 @@ import org.opencb.opencga.catalog.db.api.UserDBAdaptor; import org.opencb.opencga.catalog.exceptions.*; import org.opencb.opencga.catalog.io.CatalogIOManager; +import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.catalog.utils.UuidUtils; import org.opencb.opencga.core.api.ParamConstants; @@ -779,7 +780,7 @@ public AuthenticationResponse login(String organizationId, String username, Stri // We can only lock the account if it is not the root user int failedAttempts = userOpenCGAResult.first().getInternal().getFailedAttempts(); ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), failedAttempts + 1); - if (failedAttempts >= 4) { + if (failedAttempts >= (Constants.MAXIMUM_LOGIN_ATTEMPTS - 1)) { // Ban the account updateParams.append(UserDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), UserStatus.BANNED); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java index 8b1f4ac747e..b642d96217b 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java @@ -112,5 +112,6 @@ public class Constants { public static final String JOB_DELETED_OUTPUT_DIRECTORY = "deletedOutputFiles"; public static final String DEFAULT_USER_EXPIRATION_DATE = "21000101000000"; + public static final int MAXIMUM_LOGIN_ATTEMPTS = 5; } From 3e238e8645120c1e3bfb87d2e442231a8f2a1912 Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 23 Apr 2024 11:37:01 +0200 Subject: [PATCH 08/20] catalog: reset login attempts if it was not already 0, #TASK-6013 --- .../app/migrations/v3_1_0/UserBanMigration.java | 2 +- .../opencb/opencga/catalog/managers/UserManager.java | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java index c5507012538..ec780b20222 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/migrations/v3_1_0/UserBanMigration.java @@ -19,7 +19,7 @@ public class UserBanMigration extends MigrationTool { protected void run() throws Exception { String lastModified = TimeUtils.getTime(); migrateCollection(OrganizationMongoDBAdaptorFactory.USER_COLLECTION, - Filters.exists("internal.failedAttempts", false), + Filters.exists("internal.registrationDate", false), Projections.include("_id", "internal", "account"), (document, bulk) -> { Document internal = document.get("internal", Document.class); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index 391fc05c040..dcb61131434 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -791,6 +791,14 @@ public AuthenticationResponse login(String organizationId, String username, Stri new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError())); throw e; } + + // If it was a local user and the counter of failed attempts was greater than 0, we reset it + if (CatalogAuthenticationManager.OPENCGA.equals(userOpenCGAResult.first().getAccount().getAuthentication().getId()) + && userOpenCGAResult.first().getInternal().getFailedAttempts() > 0) { + // Reset login failed attempts counter + ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), 0); + getUserDBAdaptor(organizationId).update(username, updateParams); + } } else { // We attempt to login the user with the different authentication managers for (Map.Entry entry @@ -812,10 +820,6 @@ public AuthenticationResponse login(String organizationId, String username, Stri throw CatalogAuthenticationException.incorrectUserOrPassword(); } - // Reset login failed attempts counter - ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), 0); - getUserDBAdaptor(organizationId).update(username, updateParams); - auditManager.auditUser(organizationId, username, Enums.Action.LOGIN, username, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); String userId = authenticationFactory.getUserId(organizationId, authId, response.getToken()); From d1e95fdadf2873f716e17f4959bb3374f8e199c4 Mon Sep 17 00:00:00 2001 From: pfurio Date: Mon, 29 Apr 2024 12:28:18 +0200 Subject: [PATCH 09/20] catalog: exclude non OPENCGA users from being banned, #TASK-6013 --- .../opencb/opencga/catalog/managers/UserManager.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index dcb61131434..c968401171a 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -754,9 +754,11 @@ public AuthenticationResponse login(String organizationId, String username, Stri OpenCGAResult userOpenCGAResult = getUserDBAdaptor(organizationId).get(username, INCLUDE_ACCOUNT_AND_INTERNAL); if (userOpenCGAResult.getNumResults() == 1) { User user = userOpenCGAResult.first(); + // Only local OPENCGA users that are not superadmins can be automatically banned or their accounts be expired + boolean userCanBeBanned = !ParamConstants.ADMIN_ORGANIZATION.equals(organizationId) + && CatalogAuthenticationManager.OPENCGA.equals(user.getAccount().getAuthentication().getId()); // We check - if (!ParamConstants.ADMIN_ORGANIZATION.equals(organizationId) - && CatalogAuthenticationManager.OPENCGA.equals(user.getAccount().getAuthentication().getId())) { + if (userCanBeBanned) { // Check user is not banned, suspended or has an expired account if (UserStatus.BANNED.equals(user.getInternal().getStatus().getId())) { throw CatalogAuthenticationException.userIsBanned(username); @@ -776,7 +778,7 @@ public AuthenticationResponse login(String organizationId, String username, Stri try { response = authenticationFactory.authenticate(organizationId, authId, username, password); } catch (CatalogAuthenticationException e) { - if (!ParamConstants.ADMIN_ORGANIZATION.equals(organizationId)) { + if (userCanBeBanned) { // We can only lock the account if it is not the root user int failedAttempts = userOpenCGAResult.first().getInternal().getFailedAttempts(); ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), failedAttempts + 1); @@ -793,8 +795,7 @@ public AuthenticationResponse login(String organizationId, String username, Stri } // If it was a local user and the counter of failed attempts was greater than 0, we reset it - if (CatalogAuthenticationManager.OPENCGA.equals(userOpenCGAResult.first().getAccount().getAuthentication().getId()) - && userOpenCGAResult.first().getInternal().getFailedAttempts() > 0) { + if (userCanBeBanned && userOpenCGAResult.first().getInternal().getFailedAttempts() > 0) { // Reset login failed attempts counter ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), 0); getUserDBAdaptor(organizationId).update(username, updateParams); From 7a859647da873325b65ce357298d47d3354890df Mon Sep 17 00:00:00 2001 From: pfurio Date: Mon, 29 Apr 2024 14:51:01 +0200 Subject: [PATCH 10/20] catalog: fix organization Id null error, #TASK-6013 --- .../catalog/managers/OrganizationManager.java | 12 ++++++------ .../catalog/managers/OrganizationManagerTest.java | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java index f7e096df5c2..d487d4591f0 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java @@ -325,11 +325,11 @@ public OpenCGAResult updateUser(@Nullable String organizationId, String us .append("token", token); options = ParamUtils.defaultObject(options, QueryOptions::new); + String myOrganizationId = StringUtils.isNotEmpty(organizationId) ? organizationId : tokenPayload.getOrganization(); try { - String myOrganizationId = StringUtils.isNotEmpty(organizationId) ? organizationId : tokenPayload.getOrganization(); - authorizationManager.checkIsAtLeastOrganizationOwnerOrAdmin(myOrganizationId, tokenPayload.getUserId(organizationId)); + authorizationManager.checkIsAtLeastOrganizationOwnerOrAdmin(myOrganizationId, tokenPayload.getUserId(myOrganizationId)); ParamUtils.checkObj(updateParams, "OrganizationUserUpdateParams"); - getUserDBAdaptor(organizationId).checkId(userId); + getUserDBAdaptor(myOrganizationId).checkId(userId); if (StringUtils.isNotEmpty(updateParams.getEmail())) { ParamUtils.checkEmail(updateParams.getEmail()); @@ -359,18 +359,18 @@ public OpenCGAResult updateUser(@Nullable String organizationId, String us throw new CatalogException("Could not parse OrganizationUserUpdateParams object: " + e.getMessage(), e); } OpenCGAResult updateResult = getUserDBAdaptor(myOrganizationId).update(userId, updateMap); - auditManager.auditUpdate(organizationId, tokenPayload.getUserId(organizationId), Enums.Resource.USER, userId, "", "", "", + auditManager.auditUpdate(myOrganizationId, tokenPayload.getUserId(myOrganizationId), Enums.Resource.USER, userId, "", "", "", auditParams, new AuditRecord.Status(AuditRecord.Status.Result.SUCCESS)); if (options.getBoolean(ParamConstants.INCLUDE_RESULT_PARAM)) { // Fetch updated user - OpenCGAResult result = getUserDBAdaptor(organizationId).get(userId, options); + OpenCGAResult result = getUserDBAdaptor(myOrganizationId).get(userId, options); updateResult.setResults(result.getResults()); } return updateResult; } catch (CatalogException e) { - auditManager.auditUpdate(organizationId, tokenPayload.getUserId(organizationId), Enums.Resource.USER, userId, "", "", "", + auditManager.auditUpdate(myOrganizationId, tokenPayload.getUserId(myOrganizationId), Enums.Resource.USER, userId, "", "", "", auditParams, new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError())); throw e; } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java index c2b9550134c..8743e2e1215 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/OrganizationManagerTest.java @@ -181,7 +181,7 @@ public void updateUserInformationTest() throws CatalogException { .setAccount(new OrganizationUserUpdateParams.Account(expirationTime)) .setQuota(new UserQuota(1000, 1000000, 1000, 1000000)) .setAttributes(Collections.singletonMap("key1", "value1")); - updateAndAssertChanges(userUpdateParams, opencgaToken); + updateAndAssertChanges(organizationId, userUpdateParams, opencgaToken); userUpdateParams = new OrganizationUserUpdateParams() .setName("newName2") @@ -189,7 +189,7 @@ public void updateUserInformationTest() throws CatalogException { .setAccount(new OrganizationUserUpdateParams.Account(expirationTime)) .setQuota(new UserQuota(1001, 1010000, 1010, 1100000)) .setAttributes(Collections.singletonMap("key2", "value2")); - updateAndAssertChanges(userUpdateParams, ownerToken); + updateAndAssertChanges(null, userUpdateParams, ownerToken); userUpdateParams = new OrganizationUserUpdateParams() .setName("newName3") @@ -197,14 +197,14 @@ public void updateUserInformationTest() throws CatalogException { .setAccount(new OrganizationUserUpdateParams.Account(expirationTime)) .setQuota(new UserQuota(3001, 1010300, 1013, 1300000)) .setAttributes(Collections.singletonMap("key3", "value3")); - updateAndAssertChanges(userUpdateParams, orgAdminToken1); + updateAndAssertChanges(null, userUpdateParams, orgAdminToken1); thrown.expect(CatalogAuthorizationException.class); catalogManager.getOrganizationManager().updateUser(organizationId, normalUserId1, userUpdateParams, INCLUDE_RESULT, normalToken1); } - private void updateAndAssertChanges(OrganizationUserUpdateParams userUpdateParams, String token) throws CatalogException { - User user = catalogManager.getOrganizationManager().updateUser(organizationId, normalUserId1, userUpdateParams, INCLUDE_RESULT, token).first(); + private void updateAndAssertChanges(String orgId, OrganizationUserUpdateParams userUpdateParams, String token) throws CatalogException { + User user = catalogManager.getOrganizationManager().updateUser(orgId, normalUserId1, userUpdateParams, INCLUDE_RESULT, token).first(); assertEquals(userUpdateParams.getName(), user.getName()); assertEquals(userUpdateParams.getEmail(), user.getEmail()); assertEquals(userUpdateParams.getAccount().getExpirationDate(), user.getAccount().getExpirationDate()); From 9d304ef682a55e5ca9e225eecd9f56295c522d12 Mon Sep 17 00:00:00 2001 From: pfurio Date: Wed, 22 May 2024 14:50:58 +0200 Subject: [PATCH 11/20] core: deprecate and remove old Configuration fields, #TASK-6013 --- .../variant/OpenCGATestExternalResource.java | 2 - .../admin/executors/AdminCommandExecutor.java | 4 -- .../executors/CatalogCommandExecutor.java | 11 +-- .../opencga/catalog/utils/CatalogDemo.java | 4 +- .../opencb/opencga/core/config/Catalog.java | 21 ++++-- .../opencga/core/config/Configuration.java | 67 +++++++++---------- .../core/config/ConfigurationTest.java | 14 ---- pom.xml | 6 -- 8 files changed, 50 insertions(+), 79 deletions(-) diff --git a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java index 1f05dfc5dd3..5c5956d7cf7 100644 --- a/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java +++ b/opencga-analysis/src/test/java/org/opencb/opencga/analysis/variant/OpenCGATestExternalResource.java @@ -214,8 +214,6 @@ public Path isolateOpenCGA() throws IOException { Files.createDirectories(conf); Files.createDirectories(userHome); - catalogManagerExternalResource.getConfiguration().getAdmin().setSecretKey(null); - catalogManagerExternalResource.getConfiguration().getAdmin().setAlgorithm(null); catalogManagerExternalResource.getConfiguration().serialize( new FileOutputStream(conf.resolve("configuration.yml").toFile())); InputStream inputStream = StorageManager.class.getClassLoader().getResourceAsStream("storage-configuration.yml"); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/AdminCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/AdminCommandExecutor.java index 9dd3c922c14..f4106569f24 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/AdminCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/AdminCommandExecutor.java @@ -22,7 +22,6 @@ import org.opencb.opencga.app.cli.CommandExecutor; import org.opencb.opencga.app.cli.admin.AdminCliOptionsParser; import org.opencb.opencga.catalog.exceptions.CatalogException; -import org.opencb.opencga.core.config.Admin; import java.util.Collections; @@ -82,9 +81,6 @@ protected void setCatalogDatabaseCredentials(String host, String prefix, String configuration.getCatalog().getDatabase().setUser(user); } - if (configuration.getAdmin() == null) { - configuration.setAdmin(new Admin()); - } if (StringUtils.isNotEmpty(password)) { configuration.getCatalog().getDatabase().setPassword(password); } diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java index 5520de81126..090802f3741 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/admin/executors/CatalogCommandExecutor.java @@ -23,13 +23,11 @@ import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.datastore.mongodb.MongoDataStore; import org.opencb.opencga.app.cli.admin.AdminCliOptionsParser; -import org.opencb.opencga.catalog.auth.authentication.JwtManager; import org.opencb.opencga.catalog.db.mongodb.MongoDBAdaptorFactory; import org.opencb.opencga.catalog.db.mongodb.MongoDBUtils; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.managers.CatalogManager; import org.opencb.opencga.core.common.JacksonUtils; -import org.opencb.opencga.core.common.PasswordUtils; import org.opencb.opencga.master.monitor.MonitorService; import javax.ws.rs.client.Client; @@ -173,19 +171,12 @@ private void install() throws CatalogException { validateConfiguration(commandOptions); - this.configuration.getAdmin().setAlgorithm("HS256"); - - this.configuration.getAdmin().setSecretKey(commandOptions.secretKey); - if (StringUtils.isEmpty(configuration.getAdmin().getSecretKey())) { - configuration.getAdmin().setSecretKey(PasswordUtils.getStrongRandomPassword(JwtManager.SECRET_KEY_MIN_LENGTH)); - } - if (StringUtils.isEmpty(commandOptions.commonOptions.adminPassword)) { throw new CatalogException("No admin password found. Please, insert your password."); } try (CatalogManager catalogManager = new CatalogManager(configuration)) { - catalogManager.installCatalogDB("HS256", configuration.getAdmin().getSecretKey(), commandOptions.commonOptions.adminPassword, + catalogManager.installCatalogDB("HS256", commandOptions.secretKey, commandOptions.commonOptions.adminPassword, commandOptions.email, commandOptions.force); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/CatalogDemo.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/CatalogDemo.java index ec210c0cd79..d56f598dabb 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/CatalogDemo.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/CatalogDemo.java @@ -17,8 +17,10 @@ package org.opencb.opencga.catalog.utils; import org.opencb.commons.datastore.core.QueryOptions; +import org.opencb.opencga.catalog.auth.authentication.JwtManager; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.managers.CatalogManager; +import org.opencb.opencga.core.common.PasswordUtils; import org.opencb.opencga.core.models.organizations.OrganizationCreateParams; import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; import org.opencb.opencga.core.models.study.Group; @@ -48,7 +50,7 @@ private CatalogDemo() { */ public static void createDemoDatabase(CatalogManager catalogManager, String organizationId, String adminPassword, boolean force) throws CatalogException { - catalogManager.installCatalogDB("HS256", catalogManager.getConfiguration().getAdmin().getSecretKey(), adminPassword, + catalogManager.installCatalogDB("HS256", PasswordUtils.getStrongRandomPassword(JwtManager.SECRET_KEY_MIN_LENGTH), adminPassword, "opencga@admin.com", force); String token = catalogManager.getUserManager().loginAsAdmin(adminPassword).getToken(); try { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/Catalog.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/Catalog.java index 65fe5b7a4b8..0df3425dfba 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/Catalog.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/Catalog.java @@ -16,27 +16,33 @@ package org.opencb.opencga.core.config; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Created by pfurio on 01/02/17. */ public class Catalog { private DatabaseCredentials database; - private DatabaseCredentials searchEngine; + + private static final Logger logger; + + static { + logger = LoggerFactory.getLogger(Catalog.class); + } public Catalog() { } - public Catalog(DatabaseCredentials database, DatabaseCredentials searchEngine) { + public Catalog(DatabaseCredentials database) { this.database = database; - this.searchEngine = searchEngine; } @Override public String toString() { final StringBuilder sb = new StringBuilder("Catalog{"); sb.append("database=").append(database); - sb.append(", searchEngine=").append(searchEngine); sb.append('}'); return sb.toString(); } @@ -50,12 +56,15 @@ public Catalog setDatabase(DatabaseCredentials database) { return this; } + @Deprecated public DatabaseCredentials getSearchEngine() { - return searchEngine; + return null; } + @Deprecated public Catalog setSearchEngine(DatabaseCredentials searchEngine) { - this.searchEngine = searchEngine; + logger.warn("Ignored configuration option 'configuration.yml#catalog.searchEngine' with value '{}'." + + " The option was deprecated and removed.", searchEngine); return this; } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java index bb5057a76e2..f380c6be65d 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java @@ -40,14 +40,10 @@ public class Configuration { */ private String logDir; - @Deprecated - private boolean openRegister; - private String databasePrefix; private String workspace; private String jobDir; - private Admin admin; private Monitor monitor; private HealthCheck healthCheck; private Audit audit; @@ -59,12 +55,11 @@ public class Configuration { private Analysis analysis; private Panel panel; - private Optimizations optimizations; - private ServerConfiguration server; - private Authentication authentication; - private static Logger logger; + private static final Set reportedFields = new HashSet<>(); + + private static final Logger logger; private static final String DEFAULT_CONFIGURATION_FORMAT = "yaml"; @@ -73,7 +68,6 @@ public class Configuration { } public Configuration() { - admin = new Admin(); monitor = new Monitor(); healthCheck = new HealthCheck(); audit = new Audit(); @@ -82,9 +76,7 @@ public Configuration() { catalog = new Catalog(); analysis = new Analysis(); panel = new Panel(); - optimizations = new Optimizations(); server = new ServerConfiguration(); - authentication = new Authentication(); } public void serialize(OutputStream configurationOututStream) throws IOException { @@ -175,18 +167,6 @@ private static void overwriteWithEnvironmentVariables(Configuration configuratio case "OPENCGA_CATALOG_DB_CONNECTIONS_PER_HOST": configuration.getCatalog().getDatabase().getOptions().put("connectionsPerHost", value); break; - case "OPENCGA_CATALOG_SEARCH_HOST": - configuration.getCatalog().getSearchEngine().setHosts(Collections.singletonList(value)); - break; - case "OPENCGA_CATALOG_SEARCH_TIMEOUT": - configuration.getCatalog().getSearchEngine().getOptions().put("timeout", value); - break; - case "OPENCGA_CATALOG_SEARCH_BATCH": - configuration.getCatalog().getSearchEngine().getOptions().put("insertBatchSize", value); - break; - case "OPENCGA_OPTIMIZATIONS_SIMPLIFY_PERMISSIONS": - configuration.getOptimizations().setSimplifyPermissions(Boolean.parseBoolean(value)); - break; case "OPENCGA_SERVER_REST_PORT": configuration.getServer().getRest().setPort(Integer.parseInt(value)); break; @@ -200,6 +180,17 @@ private static void overwriteWithEnvironmentVariables(Configuration configuratio } } + public static void reportUnusedField(String field, Object value) { + // Report only if the value is not null and not an empty string + if (value != null && !(value instanceof String && ((String) value).isEmpty())) { + if (reportedFields.add(field)) { + // Only log the first time a field is found + logger.warn("Ignored configuration option 'configuration.yml#{}' with value '{}'. The option was deprecated and removed.", + field, value); + } + } + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("Configuration{"); @@ -207,16 +198,13 @@ public String toString() { sb.append(", logDir='").append(logDir).append('\''); sb.append(", databasePrefix='").append(databasePrefix).append('\''); sb.append(", workspace='").append(workspace).append('\''); - sb.append(", admin=").append(admin); sb.append(", monitor=").append(monitor); sb.append(", audit=").append(audit); sb.append(", hooks=").append(hooks); sb.append(", email=").append(email); sb.append(", catalog=").append(catalog); sb.append(", panel=").append(panel); - sb.append(", optimizations=").append(optimizations); sb.append(", server=").append(server); - sb.append(", authentication=").append(authentication); sb.append('}'); return sb.toString(); } @@ -253,13 +241,13 @@ public Configuration setLogFile(String logFile) { } @Deprecated - public boolean isOpenRegister() { - return openRegister; + public Boolean isOpenRegister() { + return null; } @Deprecated public Configuration setOpenRegister(boolean openRegister) { - this.openRegister = openRegister; + reportUnusedField("openRegister", openRegister); return this; } @@ -290,12 +278,14 @@ public Configuration setJobDir(String jobDir) { return this; } + @Deprecated public Admin getAdmin() { - return admin; + return null; } + @Deprecated public Configuration setAdmin(Admin admin) { - this.admin = admin; + reportUnusedField("admin", admin); return this; } @@ -373,12 +363,14 @@ public Configuration setPanel(Panel panel) { return this; } + @Deprecated public Optimizations getOptimizations() { - return optimizations; + return null; } + @Deprecated public Configuration setOptimizations(Optimizations optimizations) { - this.optimizations = optimizations; + reportUnusedField("optimizations", optimizations); return this; } @@ -391,12 +383,15 @@ public Configuration setServer(ServerConfiguration server) { return this; } + @Deprecated public Authentication getAuthentication() { - return authentication; + return null; } - public void setAuthentication(Authentication authentication) { - this.authentication = authentication; + @Deprecated + public Configuration setAuthentication(Authentication authentication) { + reportUnusedField("authentication", authentication); + return this; } public HealthCheck getHealthCheck() { diff --git a/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java b/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java index 948bb037dd8..9ab7cd2d224 100644 --- a/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java +++ b/opencga-core/src/test/java/org/opencb/opencga/core/config/ConfigurationTest.java @@ -37,12 +37,6 @@ public void testDefault() { configuration.setLogLevel("INFO"); configuration.setWorkspace("/opt/opencga/sessions"); - - configuration.setAdmin(new Admin()); - - Authentication authentication = new Authentication(); - configuration.setAuthentication(authentication); - configuration.setMonitor(new Monitor()); configuration.getAnalysis().setExecution(new Execution()); @@ -51,14 +45,6 @@ public void testDefault() { new HookConfiguration("name", "~*SV*", HookConfiguration.Stage.CREATE, HookConfiguration.Action.ADD, "tags", "SV") )))); - List authenticationOriginList = new ArrayList<>(); - authenticationOriginList.add(new AuthenticationOrigin()); - Map myMap = new HashMap<>(); - myMap.put("ou", "People"); - authenticationOriginList.add(new AuthenticationOrigin("opencga", AuthenticationOrigin.AuthenticationType.LDAP, - "ldap://10.10.0.20:389", myMap)); - configuration.getAuthentication().setAuthenticationOrigins(authenticationOriginList); - Email emailServer = new Email("localhost", "", "", "", "", false); configuration.setEmail(emailServer); diff --git a/pom.xml b/pom.xml index b187199de8b..cd7ea6841dd 100644 --- a/pom.xml +++ b/pom.xml @@ -1362,12 +1362,6 @@ 20 - http://localhost:8983/solr/ - 30000 - 2000 - - - false hadoop From 8f33068c9db34cfb4fe63bdd0addea9bc7169da0 Mon Sep 17 00:00:00 2001 From: pfurio Date: Wed, 22 May 2024 15:16:53 +0200 Subject: [PATCH 12/20] catalog: add maxLoginAttempts to configuration.yml file, #TASK-6013 --- .../opencga/catalog/managers/UserManager.java | 3 +- .../opencga/catalog/utils/Constants.java | 1 - .../src/test/resources/configuration-test.yml | 27 +--------- .../opencga/core/config/Configuration.java | 26 +++++++++ .../src/main/resources/configuration.yml | 54 +------------------ .../src/test/resources/configuration-test.yml | 11 +--- pom.xml | 1 + 7 files changed, 31 insertions(+), 92 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java index c968401171a..f4f6176e378 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/UserManager.java @@ -31,7 +31,6 @@ import org.opencb.opencga.catalog.db.api.UserDBAdaptor; import org.opencb.opencga.catalog.exceptions.*; import org.opencb.opencga.catalog.io.CatalogIOManager; -import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.catalog.utils.UuidUtils; import org.opencb.opencga.core.api.ParamConstants; @@ -782,7 +781,7 @@ public AuthenticationResponse login(String organizationId, String username, Stri // We can only lock the account if it is not the root user int failedAttempts = userOpenCGAResult.first().getInternal().getFailedAttempts(); ObjectMap updateParams = new ObjectMap(UserDBAdaptor.QueryParams.INTERNAL_FAILED_ATTEMPTS.key(), failedAttempts + 1); - if (failedAttempts >= (Constants.MAXIMUM_LOGIN_ATTEMPTS - 1)) { + if (failedAttempts >= (configuration.getMaxLoginAttempts() - 1)) { // Ban the account updateParams.append(UserDBAdaptor.QueryParams.INTERNAL_STATUS_ID.key(), UserStatus.BANNED); } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java index b642d96217b..8b1f4ac747e 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/utils/Constants.java @@ -112,6 +112,5 @@ public class Constants { public static final String JOB_DELETED_OUTPUT_DIRECTORY = "deletedOutputFiles"; public static final String DEFAULT_USER_EXPIRATION_DATE = "21000101000000"; - public static final int MAXIMUM_LOGIN_ATTEMPTS = 5; } diff --git a/opencga-catalog/src/test/resources/configuration-test.yml b/opencga-catalog/src/test/resources/configuration-test.yml index 7b84c12702c..2d7cbe0861a 100644 --- a/opencga-catalog/src/test/resources/configuration-test.yml +++ b/opencga-catalog/src/test/resources/configuration-test.yml @@ -6,9 +6,7 @@ databasePrefix: "opencga_test" workspace: "/tmp/opencga/sessions" jobDir: "/tmp/opencga/JOBS" - -admin: - secretKey: "asidnadh19rh230qncfascd1.rffzasf.asd.ad.12ddeASDAsd12e1d.adsx" +maxLoginAttempts: 5 audit: manager: "" # Java manager of the audit implementation to be used to audit. If empty, catalog database will be used. @@ -72,29 +70,6 @@ catalog: password: "" options: authenticationDatabase: "" - searchEngine: ## Solr configuration, by default is the same than storage - hosts: - - "http://localhost:8983/solr/" - user: "" - password: "" - options: - mode: "core" - timeout: 30000 - insertBatchSize: 2000 - -authentication: - expiration: 1000 -#LDAP configuration example -# authenticationOrigins: -# - id: ldap # Any id -# type: LDAP # At the moment, we only support LDAP -# host: ldap://localhost:9000 -# options: -# usersSearch: dc=ge,dc=co,dc=uk # Base search to look for the users -# groupsSearch: ou=general,ou=groups,dc=ge,dc=co,dc=uk # Base search to look for the groups - -optimizations: - simplifyPermissions: false server: rest: diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java index f380c6be65d..819d270f45e 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/config/Configuration.java @@ -44,6 +44,8 @@ public class Configuration { private String workspace; private String jobDir; + private int maxLoginAttempts; + private Monitor monitor; private HealthCheck healthCheck; private Audit audit; @@ -112,11 +114,19 @@ public static Configuration load(InputStream configurationInputStream, String fo throw new IOException("Configuration file could not be parsed: " + e.getMessage(), e); } + addDefaultValueIfMissing(configuration); + // We must always overwrite configuration with environment parameters overwriteWithEnvironmentVariables(configuration); return configuration; } + private static void addDefaultValueIfMissing(Configuration configuration) { + if (configuration.getMaxLoginAttempts() <= 0) { + configuration.setMaxLoginAttempts(5); + } + } + private static void overwriteWithEnvironmentVariables(Configuration configuration) { Map envVariables = System.getenv(); for (String variable : envVariables.keySet()) { @@ -136,6 +146,9 @@ private static void overwriteWithEnvironmentVariables(Configuration configuratio case "OPENCGA_MONITOR_PORT": configuration.getMonitor().setPort(Integer.parseInt(value)); break; + case "OPENCGA.MAX_LOGIN_ATTEMPTS": + configuration.setMaxLoginAttempts(Integer.parseInt(value)); + break; case "OPENCGA_EXECUTION_MODE": case "OPENCGA_EXECUTION_ID": configuration.getAnalysis().getExecution().setId(value); @@ -198,11 +211,15 @@ public String toString() { sb.append(", logDir='").append(logDir).append('\''); sb.append(", databasePrefix='").append(databasePrefix).append('\''); sb.append(", workspace='").append(workspace).append('\''); + sb.append(", jobDir='").append(jobDir).append('\''); + sb.append(", maxLoginAttempts=").append(maxLoginAttempts); sb.append(", monitor=").append(monitor); + sb.append(", healthCheck=").append(healthCheck); sb.append(", audit=").append(audit); sb.append(", hooks=").append(hooks); sb.append(", email=").append(email); sb.append(", catalog=").append(catalog); + sb.append(", analysis=").append(analysis); sb.append(", panel=").append(panel); sb.append(", server=").append(server); sb.append('}'); @@ -278,6 +295,15 @@ public Configuration setJobDir(String jobDir) { return this; } + public int getMaxLoginAttempts() { + return maxLoginAttempts; + } + + public Configuration setMaxLoginAttempts(int maxLoginAttempts) { + this.maxLoginAttempts = maxLoginAttempts; + return this; + } + @Deprecated public Admin getAdmin() { return null; diff --git a/opencga-core/src/main/resources/configuration.yml b/opencga-core/src/main/resources/configuration.yml index ac4acf283d8..bb422117d27 100644 --- a/opencga-core/src/main/resources/configuration.yml +++ b/opencga-core/src/main/resources/configuration.yml @@ -5,6 +5,7 @@ logDir: ${OPENCGA.INSTALLATION.DIR}/logs databasePrefix: ${OPENCGA.DB.PREFIX} workspace: ${OPENCGA.USER.WORKSPACE} jobDir: ${OPENCGA.USER.WORKSPACE}/jobs +maxLoginAttempts: ${OPENCGA.MAX_LOGIN_ATTEMPTS} panel: host: "http://resources.opencb.org/opencb/opencga/disease-panels" @@ -19,56 +20,6 @@ catalog: options: authenticationDatabase: ${OPENCGA.CATALOG.DB.AUTHENTICATION_DATABASE} connectionsPerHost: ${OPENCGA.CATALOG.DB.CONNECTIONS_PER_HOST} - ## Solr Search engine configuration, by default is the same than storage - searchEngine: - # List of hosts pointing either to the Solr nodes directly using a complete URL or to the zookeper nodes with HOST:PORT - # Example for Solr connection: http://opencga-solr-01.zone:8983/solr - # Example for Zookeeper connection: opencga-zookeeper-01:2181 <-- Recommended for replicated installations - hosts: - - ${OPENCGA.CATALOG.SEARCH.HOST} - user: "" - password: "" - options: - mode: "cloud" - timeout: ${OPENCGA.CATALOG.SEARCH.TIMEOUT} - insertBatchSize: ${OPENCGA.CATALOG.SEARCH.BATCH} - -## We support multiple Authentication providers, if none is provided then we use an internal authentication implementation -authentication: - # Session expiration time in seconds - expiration: 3600 - authenticationOrigins: -# Custom LDAP | LDAPS configuration example -# - id: ldaps # Any id -# type: LDAP -# host: ldaps://localhost:636 # or ldap://localhost:123 -# options: -# authUserId: "" # Auth user id and password if querying the LDAP system requires authentication. By default, empty. -# authPassword: "" # Auth user id and password if querying the LDAP system requires authentication. By default, empty. -# usersSearch: dc=ge,dc=co,dc=uk # Mandatory field. Base search to look for users. By default, empty. -# groupsSearch: ou=general,ou=groups,dc=ge,dc=co,dc=uk # Mandatory field. Base search to look for groups. By default, empty. -# fullNameKey: displayname # Key to get the user's full name when importing users. By default, 'displayname'. -# memberKey: member # Key within groups to extract the user id. By default, 'member'. -# dnKey: dn # Key to get the user's DN or RDN unique identifier. By default, 'dn'. -# dnFormat: "%s" # Formatter to extract the user's DN if it is contained within a larger string. By default, '%s' to take the whole string. -# uidKey: uid # Key to get the user id to be used in OpenCGA. By default, 'uid'. -# uidFormat: "%s" # Formatter to extract the user id if the uid is contained within a larger string. By default, '%s' to take the whole string. -# sslInvalidCertificatesAllowed: false # If using LDAPs with a custom certificate, set to true to accept any certificate. By default, false. -# connectionTimeout: 500 # Connection timeout value. Default: 500 ms -# readTimeout: 1000 # Read timeout value. Default: 1000 ms - -# Azure AD configuration example -# - id: aad # Any id -# type: AzureAD -# host: -# options: -# tenantId: xxxx # Mandatory. Tenant id -# authClientId: xxxx # Mandatory. Client id of the client with permissions to authenticate users. -# syncClientId: xxxx # Mandatory. Client id of the client with permissions to inspect active directory. -# syncSecretKey: xxxx # Mandatory: Secret key of the client with permissions to inspect active directory. -# filters: tokenField1=aa,bb,cc;tokenField2=aa,bb,cc # Optional. Filters to be applied. OpenCGA will check if tokenField1 = aa or bb -# # or cc and tokenField2 = aa or bb or cc. If any of the filters don't succeed, even if the user is properly authenticated -# # in AAD, the user will not be able to generate a token and login in OpenCGA. server: rest: @@ -80,9 +31,6 @@ server: port: ${OPENCGA.SERVER.GRPC.PORT} logFile: null -optimizations: - simplifyPermissions: ${OPENCGA_OPTIMIZATIONS_SIMPLIFY_PERMISSIONS} - audit: manager: "" # Java manager of the audit implementation to be used to audit. If empty, catalog database will be used. maxDocuments: 20000000 # Maximum number of documents that will be created in the audit collection. diff --git a/opencga-core/src/test/resources/configuration-test.yml b/opencga-core/src/test/resources/configuration-test.yml index 4d8d3c10f25..88a18dfcb53 100644 --- a/opencga-core/src/test/resources/configuration-test.yml +++ b/opencga-core/src/test/resources/configuration-test.yml @@ -4,6 +4,7 @@ logDir: null databasePrefix: "opencga_test" workspace: "/tmp/opencga/sessions" +maxLoginAttempts: 5 audit: manager: "" # Java manager of the audit implementation to be used to audit. If empty, catalog database will be used. @@ -32,16 +33,6 @@ catalog: password: "" options: authenticationDatabase: "" -authentication: - expiration: 1000 -#LDAP configuration example - authenticationOrigins: - - id: ldap # Any id - type: LDAP # At the moment, we only support LDAP - host: ldap://localhost:9000 - options: - usersSearch: dc=ge,dc=co,dc=uk # Base search to look for the users - groupsSearch: ou=general,ou=groups,dc=ge,dc=co,dc=uk # Base search to look for the groups server: rest: diff --git a/pom.xml b/pom.xml index cd7ea6841dd..0aa3fc1a931 100644 --- a/pom.xml +++ b/pom.xml @@ -1347,6 +1347,7 @@ opencga LOCAL + 5 https://ws.opencb.org/opencga-prod From 848188bd44f85256c3205809a7f5468564af5993 Mon Sep 17 00:00:00 2001 From: pfurio Date: Wed, 22 May 2024 16:09:41 +0200 Subject: [PATCH 13/20] core: add maxLoginAttempts description, #TASK-6013 --- opencga-core/src/main/resources/configuration.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opencga-core/src/main/resources/configuration.yml b/opencga-core/src/main/resources/configuration.yml index bb422117d27..4508886e77b 100644 --- a/opencga-core/src/main/resources/configuration.yml +++ b/opencga-core/src/main/resources/configuration.yml @@ -5,6 +5,8 @@ logDir: ${OPENCGA.INSTALLATION.DIR}/logs databasePrefix: ${OPENCGA.DB.PREFIX} workspace: ${OPENCGA.USER.WORKSPACE} jobDir: ${OPENCGA.USER.WORKSPACE}/jobs + +# Maximum number of login attempts before banning a user account maxLoginAttempts: ${OPENCGA.MAX_LOGIN_ATTEMPTS} panel: From 9c9cfc6e105b00bd1d2702c47707835546c90060 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 23 May 2024 15:02:18 +0200 Subject: [PATCH 14/20] app: remove catalog search configuration, #TASK-6013 --- opencga-app/app/cloud/docker/opencga-init/override_yaml.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/opencga-app/app/cloud/docker/opencga-init/override_yaml.py b/opencga-app/app/cloud/docker/opencga-init/override_yaml.py index 1993f85232b..b789aec901b 100644 --- a/opencga-app/app/cloud/docker/opencga-init/override_yaml.py +++ b/opencga-app/app/cloud/docker/opencga-init/override_yaml.py @@ -138,13 +138,6 @@ def hostOverride(conf,hosts_var): if args.catalog_database_authentication_mechanism is not None: config["catalog"]["database"]["options"]["authenticationMechanism"] = args.catalog_database_authentication_mechanism -# Inject search database -hostOverride(config["catalog"]["searchEngine"], args.catalog_search_hosts) - -if args.catalog_search_user is not None: - config["catalog"]["searchEngine"]["user"] = args.catalog_search_user - config["catalog"]["searchEngine"]["password"] = args.catalog_search_password - # Inject execution settings config["analysis"]["scratchDir"] = "/tmp/opencga_scratch" if args.max_concurrent_jobs is not None: From 2834fcf5fec57ae5fa76bc86e0b0f91368c6d1df Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 23 May 2024 15:23:52 +0200 Subject: [PATCH 15/20] app: remove catalog search configuration, #TASK-6013 --- .../opencga-init/test/test_override_yaml.py | 58 +------------------ 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/opencga-app/app/cloud/docker/opencga-init/test/test_override_yaml.py b/opencga-app/app/cloud/docker/opencga-init/test/test_override_yaml.py index 9d28765d399..ee6a547ea2b 100644 --- a/opencga-app/app/cloud/docker/opencga-init/test/test_override_yaml.py +++ b/opencga-app/app/cloud/docker/opencga-init/test/test_override_yaml.py @@ -1,11 +1,10 @@ +import os import subprocess -from shutil import copyfile +import sys import unittest import yaml from io import StringIO -import sys -import os - +from shutil import copyfile os.chdir(sys.path[0]) @@ -40,9 +39,6 @@ def test_end_2_end(self): "--catalog-database-hosts", "test-catalog-database-host1,test-catalog-database-host2,test-catalog-database-host3", "--catalog-database-user", "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", "test-catalog-search-user", - "--catalog-search-password", "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", "test-grpc-host", "--max-concurrent-jobs", "25", @@ -170,18 +166,6 @@ def test_end_2_end(self): self.assertEqual(config["catalog"]["database"]["options"]["sslEnabled"], True) self.assertEqual(config["catalog"]["database"]["options"]["sslInvalidCertificatesAllowed"], True) self.assertEqual(config["catalog"]["database"]["options"]["authenticationDatabase"], "admin") - self.assertEqual( - config["catalog"]["searchEngine"]["hosts"][0], "test-catalog-search-host1" - ) - self.assertEqual( - config["catalog"]["searchEngine"]["hosts"][1], "test-catalog-search-host2" - ) - self.assertEqual( - config["catalog"]["searchEngine"]["user"], "test-catalog-search-user" - ) - self.assertEqual( - config["catalog"]["searchEngine"]["password"], "test-catalog-search-password" - ) self.assertEqual(config["analysis"]["execution"]["id"], "test-analysis-execution-mode") self.assertEqual(config["analysis"]["execution"]["maxConcurrentJobs"]["variant-index"], 25) self.assertEqual(client_config["rest"]["hosts"][0]["url"], "test-rest-host") @@ -200,9 +184,6 @@ def test_azure_batch_execution(self): "--catalog-database-hosts", "test-catalog-database-host1,test-catalog-database-host2,test-catalog-database-host3", "--catalog-database-user", "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", "test-catalog-search-user", - "--catalog-search-password", "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", "test-grpc-host", "--analysis-execution-mode", "AZURE", @@ -273,9 +254,6 @@ def test_kubernetes_execution(self): "--catalog-database-hosts", "test-catalog-database-host1,test-catalog-database-host2,test-catalog-database-host3", "--catalog-database-user", "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", "test-catalog-search-user", - "--catalog-search-password", "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", "test-grpc-host", "--analysis-execution-mode", "k8s", @@ -357,12 +335,6 @@ def test_cellbasedb_with_empty_hosts(self): "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", - "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", - "test-catalog-search-user", - "--catalog-search-password", - "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", @@ -437,12 +409,6 @@ def test_cellbasedb_with_no_db_hosts(self): "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", - "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", - "test-catalog-search-user", - "--catalog-search-password", - "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", @@ -519,12 +485,6 @@ def test_cellbase_rest_set(self): "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", - "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", - "test-catalog-search-user", - "--catalog-search-password", - "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", @@ -604,12 +564,6 @@ def test_cellbase_rest_empty_set(self): "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", - "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", - "test-catalog-search-user", - "--catalog-search-password", - "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", @@ -688,12 +642,6 @@ def test_cellbase_rest_not_set(self): "test-catalog-database-user", "--catalog-database-password", "test-catalog-database-password", - "--catalog-search-hosts", - "test-catalog-search-host1,test-catalog-search-host2", - "--catalog-search-user", - "test-catalog-search-user", - "--catalog-search-password", - "test-catalog-search-password", "--rest-host", "test-rest-host", "--grpc-host", From 59461f7f6473b3ae0f471e6fb8002a482abeca67 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 23 May 2024 15:49:50 +0200 Subject: [PATCH 16/20] app: completely remove catalog search config, #TASK-6013 --- opencga-app/app/cloud/docker/opencga-init/override_yaml.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/opencga-app/app/cloud/docker/opencga-init/override_yaml.py b/opencga-app/app/cloud/docker/opencga-init/override_yaml.py index b789aec901b..04bd8139e82 100644 --- a/opencga-app/app/cloud/docker/opencga-init/override_yaml.py +++ b/opencga-app/app/cloud/docker/opencga-init/override_yaml.py @@ -19,9 +19,6 @@ parser.add_argument("--catalog-database-authentication-database", required=False, default="admin") parser.add_argument("--catalog-database-authentication-mechanism", required=False) parser.add_argument("--catalog-database-replica-set", required=False) -parser.add_argument("--catalog-search-hosts", required=True) -parser.add_argument("--catalog-search-user", required=False) -parser.add_argument("--catalog-search-password", required=False) parser.add_argument("--rest-host", required=True) parser.add_argument("--grpc-host", required=True) parser.add_argument("--analysis-execution-mode", required=False) From e9cb0a5ba92b202e0e090b91e0264a5a5633ca45 Mon Sep 17 00:00:00 2001 From: pfurio Date: Fri, 24 May 2024 09:30:39 +0200 Subject: [PATCH 17/20] client: update clients, #TASK-6013 --- .../app/cli/main/OpenCgaCompleter.java | 4 +- .../app/cli/main/OpencgaCliOptionsParser.java | 4 +- .../OrganizationsCommandExecutor.java | 83 ++++++++++++++++ .../main/executors/UsersCommandExecutor.java | 1 - .../options/OrganizationsCommandOptions.java | 95 +++++++++++++++++++ .../cli/main/options/UsersCommandOptions.java | 3 - opencga-client/src/main/R/R/Admin-methods.R | 2 +- .../src/main/R/R/Alignment-methods.R | 2 +- opencga-client/src/main/R/R/AllGenerics.R | 26 ++--- .../src/main/R/R/Clinical-methods.R | 4 +- opencga-client/src/main/R/R/Cohort-methods.R | 4 +- opencga-client/src/main/R/R/Family-methods.R | 4 +- opencga-client/src/main/R/R/File-methods.R | 4 +- opencga-client/src/main/R/R/GA4GH-methods.R | 4 +- .../src/main/R/R/Individual-methods.R | 4 +- opencga-client/src/main/R/R/Job-methods.R | 4 +- opencga-client/src/main/R/R/Meta-methods.R | 2 +- .../src/main/R/R/Operation-methods.R | 2 +- .../src/main/R/R/Organization-methods.R | 29 +++++- opencga-client/src/main/R/R/Panel-methods.R | 4 +- opencga-client/src/main/R/R/Project-methods.R | 4 +- opencga-client/src/main/R/R/Sample-methods.R | 4 +- opencga-client/src/main/R/R/Study-methods.R | 4 +- opencga-client/src/main/R/R/User-methods.R | 4 +- opencga-client/src/main/R/R/Variant-methods.R | 2 +- .../client/rest/clients/AdminClient.java | 4 +- .../client/rest/clients/AlignmentClient.java | 4 +- .../rest/clients/ClinicalAnalysisClient.java | 4 +- .../client/rest/clients/CohortClient.java | 4 +- .../rest/clients/DiseasePanelClient.java | 4 +- .../client/rest/clients/FamilyClient.java | 4 +- .../client/rest/clients/FileClient.java | 4 +- .../client/rest/clients/GA4GHClient.java | 4 +- .../client/rest/clients/IndividualClient.java | 4 +- .../client/rest/clients/JobClient.java | 4 +- .../client/rest/clients/MetaClient.java | 4 +- .../rest/clients/OrganizationClient.java | 43 ++++++++- .../client/rest/clients/ProjectClient.java | 4 +- .../client/rest/clients/SampleClient.java | 4 +- .../client/rest/clients/StudyClient.java | 4 +- .../client/rest/clients/UserClient.java | 4 +- .../client/rest/clients/VariantClient.java | 4 +- .../rest/clients/VariantOperationClient.java | 4 +- opencga-client/src/main/javascript/Admin.js | 2 +- .../src/main/javascript/Alignment.js | 2 +- .../src/main/javascript/ClinicalAnalysis.js | 2 +- opencga-client/src/main/javascript/Cohort.js | 2 +- .../src/main/javascript/DiseasePanel.js | 2 +- opencga-client/src/main/javascript/Family.js | 2 +- opencga-client/src/main/javascript/File.js | 2 +- opencga-client/src/main/javascript/GA4GH.js | 2 +- .../src/main/javascript/Individual.js | 2 +- opencga-client/src/main/javascript/Job.js | 2 +- opencga-client/src/main/javascript/Meta.js | 2 +- .../src/main/javascript/Organization.js | 32 ++++++- opencga-client/src/main/javascript/Project.js | 2 +- opencga-client/src/main/javascript/Sample.js | 2 +- opencga-client/src/main/javascript/Study.js | 2 +- opencga-client/src/main/javascript/User.js | 2 +- opencga-client/src/main/javascript/Variant.js | 2 +- .../src/main/javascript/VariantOperation.js | 2 +- .../pyopencga/rest_clients/admin_client.py | 4 +- .../rest_clients/alignment_client.py | 4 +- .../rest_clients/clinical_analysis_client.py | 4 +- .../pyopencga/rest_clients/cohort_client.py | 4 +- .../rest_clients/disease_panel_client.py | 4 +- .../pyopencga/rest_clients/family_client.py | 4 +- .../pyopencga/rest_clients/file_client.py | 4 +- .../pyopencga/rest_clients/ga4gh_client.py | 4 +- .../rest_clients/individual_client.py | 4 +- .../pyopencga/rest_clients/job_client.py | 4 +- .../pyopencga/rest_clients/meta_client.py | 4 +- .../rest_clients/organization_client.py | 42 +++++++- .../pyopencga/rest_clients/project_client.py | 4 +- .../pyopencga/rest_clients/sample_client.py | 4 +- .../pyopencga/rest_clients/study_client.py | 4 +- .../pyopencga/rest_clients/user_client.py | 4 +- .../pyopencga/rest_clients/variant_client.py | 4 +- .../rest_clients/variant_operation_client.py | 4 +- 79 files changed, 449 insertions(+), 141 deletions(-) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java index 1ff476d5003..9343ed8c9df 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpenCgaCompleter.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-04-29 OpenCB +* Copyright 2015-2024-05-24 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -105,7 +105,7 @@ public abstract class OpenCgaCompleter implements Completer { .map(Candidate::new) .collect(toList()); - private List organizationsList = asList( "create","notes-create","notes-search","notes-delete","notes-update","info","update") + private List organizationsList = asList( "create","notes-create","notes-search","notes-delete","notes-update","update-status-user","user-update","info","update") .stream() .map(Candidate::new) .collect(toList()); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java index f2bcf34a63c..b60ad7aafb1 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/OpencgaCliOptionsParser.java @@ -1,5 +1,5 @@ /* -* Copyright 2015-2024-04-29 OpenCB +* Copyright 2015-2024-05-24 OpenCB * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -288,6 +288,8 @@ public OpencgaCliOptionsParser() { organizationsSubCommands.addCommand("notes-search", organizationsCommandOptions.searchNotesCommandOptions); organizationsSubCommands.addCommand("notes-delete", organizationsCommandOptions.deleteNotesCommandOptions); organizationsSubCommands.addCommand("notes-update", organizationsCommandOptions.updateNotesCommandOptions); + organizationsSubCommands.addCommand("update-status-user", organizationsCommandOptions.userUpdateStatusCommandOptions); + organizationsSubCommands.addCommand("user-update", organizationsCommandOptions.updateUserCommandOptions); organizationsSubCommands.addCommand("info", organizationsCommandOptions.infoCommandOptions); organizationsSubCommands.addCommand("update", organizationsCommandOptions.updateCommandOptions); diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OrganizationsCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OrganizationsCommandExecutor.java index 991f44fd9d8..749badde15b 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OrganizationsCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/OrganizationsCommandExecutor.java @@ -23,6 +23,10 @@ import org.opencb.opencga.core.models.organizations.OrganizationCreateParams; import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; import org.opencb.opencga.core.models.organizations.TokenConfiguration; +import org.opencb.opencga.core.models.user.OrganizationUserUpdateParams; +import org.opencb.opencga.core.models.user.User; +import org.opencb.opencga.core.models.user.UserQuota; +import org.opencb.opencga.core.models.user.UserStatusUpdateParams; import org.opencb.opencga.core.response.QueryType; import org.opencb.opencga.core.response.RestResponse; @@ -75,6 +79,12 @@ public void execute() throws Exception { case "notes-update": queryResponse = updateNotes(); break; + case "update-status-user": + queryResponse = userUpdateStatus(); + break; + case "user-update": + queryResponse = updateUser(); + break; case "info": queryResponse = info(); break; @@ -116,6 +126,7 @@ private RestResponse create() throws Exception { putNestedIfNotEmpty(beanParams, "name",commandOptions.name, true); putNestedIfNotEmpty(beanParams, "creationDate",commandOptions.creationDate, true); putNestedIfNotEmpty(beanParams, "modificationDate",commandOptions.modificationDate, true); + putNestedIfNotEmpty(beanParams, "configuration.defaultUserExpirationDate",commandOptions.configurationDefaultUserExpirationDate, true); putNestedIfNotNull(beanParams, "attributes",commandOptions.attributes, true); organizationCreateParams = JacksonUtils.getDefaultObjectMapper().copy() @@ -223,6 +234,77 @@ private RestResponse updateNotes() throws Exception { return openCGAClient.getOrganizationClient().updateNotes(commandOptions.id, noteUpdateParams, queryParams); } + private RestResponse userUpdateStatus() throws Exception { + logger.debug("Executing userUpdateStatus in Organizations command line"); + + OrganizationsCommandOptions.UserUpdateStatusCommandOptions commandOptions = organizationsCommandOptions.userUpdateStatusCommandOptions; + + ObjectMap queryParams = new ObjectMap(); + queryParams.putIfNotEmpty("include", commandOptions.include); + queryParams.putIfNotEmpty("exclude", commandOptions.exclude); + queryParams.putIfNotEmpty("organization", commandOptions.organization); + queryParams.putIfNotNull("includeResult", commandOptions.includeResult); + + + UserStatusUpdateParams userStatusUpdateParams = null; + if (commandOptions.jsonDataModel) { + RestResponse res = new RestResponse<>(); + res.setType(QueryType.VOID); + PrintUtils.println(getObjectAsJSON(categoryName,"/{apiVersion}/organizations/user/{user}/status/update")); + return res; + } else if (commandOptions.jsonFile != null) { + userStatusUpdateParams = JacksonUtils.getDefaultObjectMapper() + .readValue(new java.io.File(commandOptions.jsonFile), UserStatusUpdateParams.class); + } else { + ObjectMap beanParams = new ObjectMap(); + putNestedIfNotEmpty(beanParams, "status",commandOptions.status, true); + + userStatusUpdateParams = JacksonUtils.getDefaultObjectMapper().copy() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true) + .readValue(beanParams.toJson(), UserStatusUpdateParams.class); + } + return openCGAClient.getOrganizationClient().userUpdateStatus(commandOptions.user, userStatusUpdateParams, queryParams); + } + + private RestResponse updateUser() throws Exception { + logger.debug("Executing updateUser in Organizations command line"); + + OrganizationsCommandOptions.UpdateUserCommandOptions commandOptions = organizationsCommandOptions.updateUserCommandOptions; + + ObjectMap queryParams = new ObjectMap(); + queryParams.putIfNotEmpty("include", commandOptions.include); + queryParams.putIfNotEmpty("exclude", commandOptions.exclude); + queryParams.putIfNotEmpty("organization", commandOptions.organization); + queryParams.putIfNotNull("includeResult", commandOptions.includeResult); + + + OrganizationUserUpdateParams organizationUserUpdateParams = null; + if (commandOptions.jsonDataModel) { + RestResponse res = new RestResponse<>(); + res.setType(QueryType.VOID); + PrintUtils.println(getObjectAsJSON(categoryName,"/{apiVersion}/organizations/user/{user}/update")); + return res; + } else if (commandOptions.jsonFile != null) { + organizationUserUpdateParams = JacksonUtils.getDefaultObjectMapper() + .readValue(new java.io.File(commandOptions.jsonFile), OrganizationUserUpdateParams.class); + } else { + ObjectMap beanParams = new ObjectMap(); + putNestedIfNotEmpty(beanParams, "name",commandOptions.name, true); + putNestedIfNotEmpty(beanParams, "email",commandOptions.email, true); + putNestedIfNotNull(beanParams, "quota.diskUsage",commandOptions.quotaDiskUsage, true); + putNestedIfNotNull(beanParams, "quota.cpuUsage",commandOptions.quotaCpuUsage, true); + putNestedIfNotNull(beanParams, "quota.maxDisk",commandOptions.quotaMaxDisk, true); + putNestedIfNotNull(beanParams, "quota.maxCpu",commandOptions.quotaMaxCpu, true); + putNestedIfNotEmpty(beanParams, "account.expirationDate",commandOptions.accountExpirationDate, true); + putNestedIfNotNull(beanParams, "attributes",commandOptions.attributes, true); + + organizationUserUpdateParams = JacksonUtils.getDefaultObjectMapper().copy() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true) + .readValue(beanParams.toJson(), OrganizationUserUpdateParams.class); + } + return openCGAClient.getOrganizationClient().updateUser(commandOptions.user, organizationUserUpdateParams, queryParams); + } + private RestResponse info() throws Exception { logger.debug("Executing info in Organizations command line"); @@ -263,6 +345,7 @@ private RestResponse update() throws Exception { putNestedIfNotNull(beanParams, "admins",commandOptions.admins, true); putNestedIfNotEmpty(beanParams, "creationDate",commandOptions.creationDate, true); putNestedIfNotEmpty(beanParams, "modificationDate",commandOptions.modificationDate, true); + putNestedIfNotEmpty(beanParams, "configuration.defaultUserExpirationDate",commandOptions.configurationDefaultUserExpirationDate, true); putNestedIfNotNull(beanParams, "attributes",commandOptions.attributes, true); organizationUpdateParams = JacksonUtils.getDefaultObjectMapper().copy() diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/UsersCommandExecutor.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/UsersCommandExecutor.java index 6eeeae17408..4883cedef5c 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/UsersCommandExecutor.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/executors/UsersCommandExecutor.java @@ -305,7 +305,6 @@ private RestResponse update() throws Exception { ObjectMap beanParams = new ObjectMap(); putNestedIfNotEmpty(beanParams, "name",commandOptions.name, true); putNestedIfNotEmpty(beanParams, "email",commandOptions.email, true); - putNestedIfNotNull(beanParams, "attributes",commandOptions.attributes, true); userUpdateParams = JacksonUtils.getDefaultObjectMapper().copy() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true) diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OrganizationsCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OrganizationsCommandOptions.java index c2ab1e89a90..082a1ad71c9 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OrganizationsCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/OrganizationsCommandOptions.java @@ -38,6 +38,8 @@ public class OrganizationsCommandOptions { public SearchNotesCommandOptions searchNotesCommandOptions; public DeleteNotesCommandOptions deleteNotesCommandOptions; public UpdateNotesCommandOptions updateNotesCommandOptions; + public UserUpdateStatusCommandOptions userUpdateStatusCommandOptions; + public UpdateUserCommandOptions updateUserCommandOptions; public InfoCommandOptions infoCommandOptions; public UpdateCommandOptions updateCommandOptions; @@ -51,6 +53,8 @@ public OrganizationsCommandOptions(CommonCommandOptions commonCommandOptions, JC this.searchNotesCommandOptions = new SearchNotesCommandOptions(); this.deleteNotesCommandOptions = new DeleteNotesCommandOptions(); this.updateNotesCommandOptions = new UpdateNotesCommandOptions(); + this.userUpdateStatusCommandOptions = new UserUpdateStatusCommandOptions(); + this.updateUserCommandOptions = new UpdateUserCommandOptions(); this.infoCommandOptions = new InfoCommandOptions(); this.updateCommandOptions = new UpdateCommandOptions(); @@ -89,6 +93,9 @@ public class CreateCommandOptions { @Parameter(names = {"--modification-date", "--md"}, description = "Autogenerated date following the format YYYYMMDDhhmmss containing the date when the entry was last modified.", required = false, arity = 1) public String modificationDate; + @Parameter(names = {"--configuration-default-user-expiration-date"}, description = "The body web service defaultUserExpirationDate parameter", required = false, arity = 1) + public String configurationDefaultUserExpirationDate; + @DynamicParameter(names = {"--attributes"}, description = "You can use this field to store any other information, keep in mind this is not indexed so you cannot search by attributes.. Use: --attributes key=value", required = false) public java.util.Map attributes = new HashMap<>(); //Dynamic parameters must be initialized; @@ -216,6 +223,91 @@ public class UpdateNotesCommandOptions { } + @Parameters(commandNames = {"update-status-user"}, commandDescription ="Update the user status") + public class UserUpdateStatusCommandOptions { + + @ParametersDelegate + public CommonCommandOptions commonOptions = commonCommandOptions; + + @Parameter(names = {"--json-file"}, description = "File with the body data in JSON format. Note, that using this parameter will ignore all the other parameters.", required = false, arity = 1) + public String jsonFile; + + @Parameter(names = {"--json-data-model"}, description = "Show example of file structure for body data.", help = true, arity = 0) + public Boolean jsonDataModel = false; + + @Parameter(names = {"--include", "-I"}, description = "Fields included in the response, whole JSON path must be provided", required = false, arity = 1) + public String include; + + @Parameter(names = {"--exclude", "-E"}, description = "Fields excluded in the response, whole JSON path must be provided", required = false, arity = 1) + public String exclude; + + @Parameter(names = {"--user", "-u"}, description = "User ID", required = true, arity = 1) + public String user; + + @Parameter(names = {"--organization"}, description = "Organization id", required = false, arity = 1) + public String organization; + + @Parameter(names = {"--include-result"}, description = "Flag indicating to include the created or updated document result in the response", required = false, help = true, arity = 0) + public boolean includeResult = false; + + @Parameter(names = {"--status"}, description = "The body web service status parameter", required = false, arity = 1) + public String status; + + } + + @Parameters(commandNames = {"user-update"}, commandDescription ="Update the user information") + public class UpdateUserCommandOptions { + + @ParametersDelegate + public CommonCommandOptions commonOptions = commonCommandOptions; + + @Parameter(names = {"--json-file"}, description = "File with the body data in JSON format. Note, that using this parameter will ignore all the other parameters.", required = false, arity = 1) + public String jsonFile; + + @Parameter(names = {"--json-data-model"}, description = "Show example of file structure for body data.", help = true, arity = 0) + public Boolean jsonDataModel = false; + + @Parameter(names = {"--include", "-I"}, description = "Fields included in the response, whole JSON path must be provided", required = false, arity = 1) + public String include; + + @Parameter(names = {"--exclude", "-E"}, description = "Fields excluded in the response, whole JSON path must be provided", required = false, arity = 1) + public String exclude; + + @Parameter(names = {"--user", "-u"}, description = "User ID", required = true, arity = 1) + public String user; + + @Parameter(names = {"--organization"}, description = "Organization id", required = false, arity = 1) + public String organization; + + @Parameter(names = {"--include-result"}, description = "Flag indicating to include the created or updated document result in the response", required = false, help = true, arity = 0) + public boolean includeResult = false; + + @Parameter(names = {"--name", "-n"}, description = "The body web service name parameter", required = false, arity = 1) + public String name; + + @Parameter(names = {"--email"}, description = "The body web service email parameter", required = false, arity = 1) + public String email; + + @Parameter(names = {"--quota-disk-usage"}, description = "The body web service diskUsage parameter", required = false, arity = 1) + public Long quotaDiskUsage; + + @Parameter(names = {"--quota-cpu-usage"}, description = "The body web service cpuUsage parameter", required = false, arity = 1) + public Integer quotaCpuUsage; + + @Parameter(names = {"--quota-max-disk"}, description = "The body web service maxDisk parameter", required = false, arity = 1) + public Long quotaMaxDisk; + + @Parameter(names = {"--quota-max-cpu"}, description = "The body web service maxCpu parameter", required = false, arity = 1) + public Integer quotaMaxCpu; + + @Parameter(names = {"--account-expiration-date"}, description = "The body web service expirationDate parameter", required = false, arity = 1) + public String accountExpirationDate; + + @DynamicParameter(names = {"--attributes"}, description = "The body web service attributes parameter. Use: --attributes key=value", required = false) + public java.util.Map attributes = new HashMap<>(); //Dynamic parameters must be initialized; + + } + @Parameters(commandNames = {"info"}, commandDescription ="Return the organization information") public class InfoCommandOptions { @@ -275,6 +367,9 @@ public class UpdateCommandOptions { @Parameter(names = {"--modification-date", "--md"}, description = "Autogenerated date following the format YYYYMMDDhhmmss containing the date when the entry was last modified.", required = false, arity = 1) public String modificationDate; + @Parameter(names = {"--configuration-default-user-expiration-date"}, description = "The body web service defaultUserExpirationDate parameter", required = false, arity = 1) + public String configurationDefaultUserExpirationDate; + @DynamicParameter(names = {"--attributes"}, description = "You can use this field to store any other information, keep in mind this is not indexed so you cannot search by attributes.. Use: --attributes key=value", required = false) public java.util.Map attributes = new HashMap<>(); //Dynamic parameters must be initialized; diff --git a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/UsersCommandOptions.java b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/UsersCommandOptions.java index 885a2ffaa70..66d7cee55a8 100644 --- a/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/UsersCommandOptions.java +++ b/opencga-app/src/main/java/org/opencb/opencga/app/cli/main/options/UsersCommandOptions.java @@ -285,9 +285,6 @@ public class UpdateCommandOptions { @Parameter(names = {"--email"}, description = "The body web service email parameter", required = false, arity = 1) public String email; - @DynamicParameter(names = {"--attributes"}, description = "The body web service attributes parameter. Use: --attributes key=value", required = false) - public java.util.Map attributes = new HashMap<>(); //Dynamic parameters must be initialized; - } } \ No newline at end of file diff --git a/opencga-client/src/main/R/R/Admin-methods.R b/opencga-client/src/main/R/R/Admin-methods.R index 21ccff3b4da..9afff09ecde 100644 --- a/opencga-client/src/main/R/R/Admin-methods.R +++ b/opencga-client/src/main/R/R/Admin-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Alignment-methods.R b/opencga-client/src/main/R/R/Alignment-methods.R index 363efca3f8f..e242b69f6ec 100644 --- a/opencga-client/src/main/R/R/Alignment-methods.R +++ b/opencga-client/src/main/R/R/Alignment-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/AllGenerics.R b/opencga-client/src/main/R/R/AllGenerics.R index 3d6e69ee4cb..f70713833af 100644 --- a/opencga-client/src/main/R/R/AllGenerics.R +++ b/opencga-client/src/main/R/R/AllGenerics.R @@ -1,56 +1,56 @@ # ############################################################################## ## OrganizationClient -setGeneric("organizationClient", function(OpencgaR, organization, id, endpointName, params=NULL, ...) +setGeneric("organizationClient", function(OpencgaR, id, user, organization, endpointName, params=NULL, ...) standardGeneric("organizationClient")) # ############################################################################## ## UserClient -setGeneric("userClient", function(OpencgaR, users, filterId, user, endpointName, params=NULL, ...) +setGeneric("userClient", function(OpencgaR, users, user, filterId, endpointName, params=NULL, ...) standardGeneric("userClient")) # ############################################################################## ## ProjectClient -setGeneric("projectClient", function(OpencgaR, project, projects, endpointName, params=NULL, ...) +setGeneric("projectClient", function(OpencgaR, projects, project, endpointName, params=NULL, ...) standardGeneric("projectClient")) # ############################################################################## ## StudyClient -setGeneric("studyClient", function(OpencgaR, members, group, id, variableSet, templateId, study, studies, endpointName, params=NULL, ...) +setGeneric("studyClient", function(OpencgaR, id, studies, members, study, variableSet, group, templateId, endpointName, params=NULL, ...) standardGeneric("studyClient")) # ############################################################################## ## FileClient -setGeneric("fileClient", function(OpencgaR, members, folder, files, annotationSet, file, endpointName, params=NULL, ...) +setGeneric("fileClient", function(OpencgaR, annotationSet, members, folder, file, files, endpointName, params=NULL, ...) standardGeneric("fileClient")) # ############################################################################## ## JobClient -setGeneric("jobClient", function(OpencgaR, members, jobs, job, endpointName, params=NULL, ...) +setGeneric("jobClient", function(OpencgaR, job, jobs, members, endpointName, params=NULL, ...) standardGeneric("jobClient")) # ############################################################################## ## SampleClient -setGeneric("sampleClient", function(OpencgaR, members, samples, annotationSet, sample, endpointName, params=NULL, ...) +setGeneric("sampleClient", function(OpencgaR, annotationSet, samples, members, sample, endpointName, params=NULL, ...) standardGeneric("sampleClient")) # ############################################################################## ## IndividualClient -setGeneric("individualClient", function(OpencgaR, members, individuals, individual, annotationSet, endpointName, params=NULL, ...) +setGeneric("individualClient", function(OpencgaR, annotationSet, individuals, individual, members, endpointName, params=NULL, ...) standardGeneric("individualClient")) # ############################################################################## ## FamilyClient -setGeneric("familyClient", function(OpencgaR, members, families, annotationSet, family, endpointName, params=NULL, ...) +setGeneric("familyClient", function(OpencgaR, annotationSet, families, family, members, endpointName, params=NULL, ...) standardGeneric("familyClient")) # ############################################################################## ## CohortClient -setGeneric("cohortClient", function(OpencgaR, members, annotationSet, cohort, cohorts, endpointName, params=NULL, ...) +setGeneric("cohortClient", function(OpencgaR, cohorts, annotationSet, cohort, members, endpointName, params=NULL, ...) standardGeneric("cohortClient")) # ############################################################################## ## PanelClient -setGeneric("panelClient", function(OpencgaR, members, panels, endpointName, params=NULL, ...) +setGeneric("panelClient", function(OpencgaR, panels, members, endpointName, params=NULL, ...) standardGeneric("panelClient")) # ############################################################################## @@ -65,7 +65,7 @@ setGeneric("variantClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## ClinicalClient -setGeneric("clinicalClient", function(OpencgaR, members, interpretation, clinicalAnalysis, clinicalAnalyses, interpretations, annotationSet, endpointName, params=NULL, ...) +setGeneric("clinicalClient", function(OpencgaR, interpretation, interpretations, annotationSet, members, clinicalAnalysis, clinicalAnalyses, endpointName, params=NULL, ...) standardGeneric("clinicalClient")) # ############################################################################## @@ -80,7 +80,7 @@ setGeneric("metaClient", function(OpencgaR, endpointName, params=NULL, ...) # ############################################################################## ## GA4GHClient -setGeneric("ga4ghClient", function(OpencgaR, study, file, endpointName, params=NULL, ...) +setGeneric("ga4ghClient", function(OpencgaR, file, study, endpointName, params=NULL, ...) standardGeneric("ga4ghClient")) # ############################################################################## diff --git a/opencga-client/src/main/R/R/Clinical-methods.R b/opencga-client/src/main/R/R/Clinical-methods.R index 675d8f0c9bb..1a5970612fd 100644 --- a/opencga-client/src/main/R/R/Clinical-methods.R +++ b/opencga-client/src/main/R/R/Clinical-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -62,7 +62,7 @@ #' [*]: Required parameter #' @export -setMethod("clinicalClient", "OpencgaR", function(OpencgaR, members, interpretation, clinicalAnalysis, clinicalAnalyses, interpretations, annotationSet, endpointName, params=NULL, ...) { +setMethod("clinicalClient", "OpencgaR", function(OpencgaR, interpretation, interpretations, annotationSet, members, clinicalAnalysis, clinicalAnalyses, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/analysis/clinical/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Cohort-methods.R b/opencga-client/src/main/R/R/Cohort-methods.R index 771d7d16480..3bc72f8bdc4 100644 --- a/opencga-client/src/main/R/R/Cohort-methods.R +++ b/opencga-client/src/main/R/R/Cohort-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("cohortClient", "OpencgaR", function(OpencgaR, members, annotationSet, cohort, cohorts, endpointName, params=NULL, ...) { +setMethod("cohortClient", "OpencgaR", function(OpencgaR, cohorts, annotationSet, cohort, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/cohorts/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Family-methods.R b/opencga-client/src/main/R/R/Family-methods.R index dc1ad726ed4..08882b36b54 100644 --- a/opencga-client/src/main/R/R/Family-methods.R +++ b/opencga-client/src/main/R/R/Family-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -37,7 +37,7 @@ #' [*]: Required parameter #' @export -setMethod("familyClient", "OpencgaR", function(OpencgaR, members, families, annotationSet, family, endpointName, params=NULL, ...) { +setMethod("familyClient", "OpencgaR", function(OpencgaR, annotationSet, families, family, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/families/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/File-methods.R b/opencga-client/src/main/R/R/File-methods.R index 52d5b80e3f6..c7571f7459f 100644 --- a/opencga-client/src/main/R/R/File-methods.R +++ b/opencga-client/src/main/R/R/File-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -54,7 +54,7 @@ #' [*]: Required parameter #' @export -setMethod("fileClient", "OpencgaR", function(OpencgaR, members, folder, files, annotationSet, file, endpointName, params=NULL, ...) { +setMethod("fileClient", "OpencgaR", function(OpencgaR, annotationSet, members, folder, file, files, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/files/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/GA4GH-methods.R b/opencga-client/src/main/R/R/GA4GH-methods.R index b134810eeb3..8851832c75e 100644 --- a/opencga-client/src/main/R/R/GA4GH-methods.R +++ b/opencga-client/src/main/R/R/GA4GH-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -31,7 +31,7 @@ #' [*]: Required parameter #' @export -setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, study, file, endpointName, params=NULL, ...) { +setMethod("ga4ghClient", "OpencgaR", function(OpencgaR, file, study, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/ga4gh/reads/search: diff --git a/opencga-client/src/main/R/R/Individual-methods.R b/opencga-client/src/main/R/R/Individual-methods.R index ab204922c49..c2876126b27 100644 --- a/opencga-client/src/main/R/R/Individual-methods.R +++ b/opencga-client/src/main/R/R/Individual-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("individualClient", "OpencgaR", function(OpencgaR, members, individuals, individual, annotationSet, endpointName, params=NULL, ...) { +setMethod("individualClient", "OpencgaR", function(OpencgaR, annotationSet, individuals, individual, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/individuals/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Job-methods.R b/opencga-client/src/main/R/R/Job-methods.R index c48e3ae9691..1a5932fd64b 100644 --- a/opencga-client/src/main/R/R/Job-methods.R +++ b/opencga-client/src/main/R/R/Job-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -39,7 +39,7 @@ #' [*]: Required parameter #' @export -setMethod("jobClient", "OpencgaR", function(OpencgaR, members, jobs, job, endpointName, params=NULL, ...) { +setMethod("jobClient", "OpencgaR", function(OpencgaR, job, jobs, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/jobs/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Meta-methods.R b/opencga-client/src/main/R/R/Meta-methods.R index 8fd2202e69f..eab23e786c9 100644 --- a/opencga-client/src/main/R/R/Meta-methods.R +++ b/opencga-client/src/main/R/R/Meta-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Operation-methods.R b/opencga-client/src/main/R/R/Operation-methods.R index 868d718b61c..e4ed07da8c8 100644 --- a/opencga-client/src/main/R/R/Operation-methods.R +++ b/opencga-client/src/main/R/R/Operation-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/R/R/Organization-methods.R b/opencga-client/src/main/R/R/Organization-methods.R index fd5681c5378..66e0c463d82 100644 --- a/opencga-client/src/main/R/R/Organization-methods.R +++ b/opencga-client/src/main/R/R/Organization-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -25,6 +25,8 @@ #' | searchNotes | /{apiVersion}/organizations/notes/search | include, exclude, creationDate, modificationDate, id, scope, visibility, uuid, userId, tags, version | #' | deleteNotes | /{apiVersion}/organizations/notes/{id}/delete | id[*], includeResult | #' | updateNotes | /{apiVersion}/organizations/notes/{id}/update | include, exclude, id[*], includeResult, body[*] | +#' | userUpdateStatus | /{apiVersion}/organizations/user/{user}/status/update | include, exclude, user[*], organization, includeResult, body[*] | +#' | updateUser | /{apiVersion}/organizations/user/{user}/update | include, exclude, user[*], organization, includeResult, body[*] | #' | info | /{apiVersion}/organizations/{organization}/info | include, exclude, organization[*] | #' | update | /{apiVersion}/organizations/{organization}/update | include, exclude, organization[*], includeResult, adminsAction, body[*] | #' @@ -34,7 +36,7 @@ #' [*]: Required parameter #' @export -setMethod("organizationClient", "OpencgaR", function(OpencgaR, organization, id, endpointName, params=NULL, ...) { +setMethod("organizationClient", "OpencgaR", function(OpencgaR, id, user, organization, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/organizations/create: @@ -88,6 +90,29 @@ setMethod("organizationClient", "OpencgaR", function(OpencgaR, organization, id, updateNotes=fetchOpenCGA(object=OpencgaR, category="organizations", categoryId=NULL, subcategory="notes", subcategoryId=id, action="update", params=params, httpMethod="POST", as.queryParam=NULL, ...), + #' @section Endpoint /{apiVersion}/organizations/user/{user}/status/update: + #' Update the user status. + #' @param include Fields included in the response, whole JSON path must be provided. + #' @param exclude Fields excluded in the response, whole JSON path must be provided. + #' @param user User ID. + #' @param organization Organization id. + #' @param includeResult Flag indicating to include the created or updated document result in the response. + #' @param data JSON containing the User fields to be updated. + userUpdateStatus=fetchOpenCGA(object=OpencgaR, category="organizations/user", categoryId=user, + subcategory="status", subcategoryId=NULL, action="update", params=params, httpMethod="POST", + as.queryParam=NULL, ...), + + #' @section Endpoint /{apiVersion}/organizations/user/{user}/update: + #' Update the user information. + #' @param include Fields included in the response, whole JSON path must be provided. + #' @param exclude Fields excluded in the response, whole JSON path must be provided. + #' @param user User ID. + #' @param organization Organization id. + #' @param includeResult Flag indicating to include the created or updated document result in the response. + #' @param data JSON containing the User fields to be updated. + updateUser=fetchOpenCGA(object=OpencgaR, category="organizations", categoryId=NULL, subcategory="user", + subcategoryId=user, action="update", params=params, httpMethod="POST", as.queryParam=NULL, ...), + #' @section Endpoint /{apiVersion}/organizations/{organization}/info: #' Return the organization information. #' @param include Fields included in the response, whole JSON path must be provided. diff --git a/opencga-client/src/main/R/R/Panel-methods.R b/opencga-client/src/main/R/R/Panel-methods.R index 6f9d0bebb47..6df03471df2 100644 --- a/opencga-client/src/main/R/R/Panel-methods.R +++ b/opencga-client/src/main/R/R/Panel-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -36,7 +36,7 @@ #' [*]: Required parameter #' @export -setMethod("panelClient", "OpencgaR", function(OpencgaR, members, panels, endpointName, params=NULL, ...) { +setMethod("panelClient", "OpencgaR", function(OpencgaR, panels, members, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/panels/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Project-methods.R b/opencga-client/src/main/R/R/Project-methods.R index 41235ecea72..83be290c608 100644 --- a/opencga-client/src/main/R/R/Project-methods.R +++ b/opencga-client/src/main/R/R/Project-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -33,7 +33,7 @@ #' [*]: Required parameter #' @export -setMethod("projectClient", "OpencgaR", function(OpencgaR, project, projects, endpointName, params=NULL, ...) { +setMethod("projectClient", "OpencgaR", function(OpencgaR, projects, project, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/projects/create: diff --git a/opencga-client/src/main/R/R/Sample-methods.R b/opencga-client/src/main/R/R/Sample-methods.R index b61ca7558ca..9a90e67aad4 100644 --- a/opencga-client/src/main/R/R/Sample-methods.R +++ b/opencga-client/src/main/R/R/Sample-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -38,7 +38,7 @@ #' [*]: Required parameter #' @export -setMethod("sampleClient", "OpencgaR", function(OpencgaR, members, samples, annotationSet, sample, endpointName, params=NULL, ...) { +setMethod("sampleClient", "OpencgaR", function(OpencgaR, annotationSet, samples, members, sample, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/samples/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/Study-methods.R b/opencga-client/src/main/R/R/Study-methods.R index 81f0e582a7c..48d1c32e5ce 100644 --- a/opencga-client/src/main/R/R/Study-methods.R +++ b/opencga-client/src/main/R/R/Study-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -49,7 +49,7 @@ #' [*]: Required parameter #' @export -setMethod("studyClient", "OpencgaR", function(OpencgaR, members, group, id, variableSet, templateId, study, studies, endpointName, params=NULL, ...) { +setMethod("studyClient", "OpencgaR", function(OpencgaR, id, studies, members, study, variableSet, group, templateId, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/studies/acl/{members}/update: diff --git a/opencga-client/src/main/R/R/User-methods.R b/opencga-client/src/main/R/R/User-methods.R index 4b6e2d76c67..7f4cfa15ed1 100644 --- a/opencga-client/src/main/R/R/User-methods.R +++ b/opencga-client/src/main/R/R/User-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. @@ -40,7 +40,7 @@ #' [*]: Required parameter #' @export -setMethod("userClient", "OpencgaR", function(OpencgaR, users, filterId, user, endpointName, params=NULL, ...) { +setMethod("userClient", "OpencgaR", function(OpencgaR, users, user, filterId, endpointName, params=NULL, ...) { switch(endpointName, #' @section Endpoint /{apiVersion}/users/anonymous: diff --git a/opencga-client/src/main/R/R/Variant-methods.R b/opencga-client/src/main/R/R/Variant-methods.R index 8bc5c25558b..38429602cf4 100644 --- a/opencga-client/src/main/R/R/Variant-methods.R +++ b/opencga-client/src/main/R/R/Variant-methods.R @@ -2,7 +2,7 @@ # WARNING: AUTOGENERATED CODE # # This code was generated by a tool. -# Autogenerated on: 2024-04-29 +# Autogenerated on: 2024-05-24 # # Manual changes to this file may cause unexpected behavior in your application. # Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java index a74cbd784c4..b268f7d4e32 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AdminClient.java @@ -37,7 +37,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -46,7 +46,7 @@ /** * This class contains methods for the Admin webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: admin */ public class AdminClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java index 5d3cef8c796..ba51d5e8e25 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/AlignmentClient.java @@ -40,7 +40,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -49,7 +49,7 @@ /** * This class contains methods for the Alignment webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: analysis/alignment */ public class AlignmentClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java index f12aa75b765..7e08ca0fbf0 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ClinicalAnalysisClient.java @@ -55,7 +55,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -64,7 +64,7 @@ /** * This class contains methods for the ClinicalAnalysis webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: analysis/clinical */ public class ClinicalAnalysisClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java index 127e40de626..62245025d7b 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/CohortClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Cohort webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: cohorts */ public class CohortClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java index d55854b6127..a2061dc74f1 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/DiseasePanelClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -44,7 +44,7 @@ /** * This class contains methods for the DiseasePanel webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: panels */ public class DiseasePanelClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java index 663903149db..a9641be2a54 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FamilyClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -44,7 +44,7 @@ /** * This class contains methods for the Family webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: families */ public class FamilyClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java index 0fe1fba1940..67d7187c9f3 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/FileClient.java @@ -43,7 +43,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -52,7 +52,7 @@ /** * This class contains methods for the File webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: files */ public class FileClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java index 0e14eba34d8..fe9d3a915ee 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/GA4GHClient.java @@ -27,7 +27,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -36,7 +36,7 @@ /** * This class contains methods for the GA4GH webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: ga4gh */ public class GA4GHClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java index 5598bf2ec81..436a15bd4d7 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/IndividualClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -44,7 +44,7 @@ /** * This class contains methods for the Individual webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: individuals */ public class IndividualClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java index 02037990104..80cff12cf64 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/JobClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the Job webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: jobs */ public class JobClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java index 8826ff88f90..7e48396cb39 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/MetaClient.java @@ -28,7 +28,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -37,7 +37,7 @@ /** * This class contains methods for the Meta webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: meta */ public class MetaClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/OrganizationClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/OrganizationClient.java index e1ec2b30ebf..0367fe9b389 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/OrganizationClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/OrganizationClient.java @@ -26,6 +26,9 @@ import org.opencb.opencga.core.models.organizations.Organization; import org.opencb.opencga.core.models.organizations.OrganizationCreateParams; import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; +import org.opencb.opencga.core.models.user.OrganizationUserUpdateParams; +import org.opencb.opencga.core.models.user.User; +import org.opencb.opencga.core.models.user.UserStatusUpdateParams; import org.opencb.opencga.core.response.RestResponse; @@ -33,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -42,7 +45,7 @@ /** * This class contains methods for the Organization webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: organizations */ public class OrganizationClient extends AbstractParentClient { @@ -136,6 +139,42 @@ public RestResponse updateNotes(String id, NoteUpdateParams data, ObjectMa return execute("organizations", null, "notes", id, "update", params, POST, Note.class); } + /** + * Update the user status. + * @param user User ID. + * @param data JSON containing the User fields to be updated. + * @param params Map containing any of the following optional parameters. + * include: Fields included in the response, whole JSON path must be provided. + * exclude: Fields excluded in the response, whole JSON path must be provided. + * organization: Organization id. + * includeResult: Flag indicating to include the created or updated document result in the response. + * @return a RestResponse object. + * @throws ClientException ClientException if there is any server error. + */ + public RestResponse userUpdateStatus(String user, UserStatusUpdateParams data, ObjectMap params) throws ClientException { + params = params != null ? params : new ObjectMap(); + params.put("body", data); + return execute("organizations/user", user, "status", null, "update", params, POST, User.class); + } + + /** + * Update the user information. + * @param user User ID. + * @param data JSON containing the User fields to be updated. + * @param params Map containing any of the following optional parameters. + * include: Fields included in the response, whole JSON path must be provided. + * exclude: Fields excluded in the response, whole JSON path must be provided. + * organization: Organization id. + * includeResult: Flag indicating to include the created or updated document result in the response. + * @return a RestResponse object. + * @throws ClientException ClientException if there is any server error. + */ + public RestResponse updateUser(String user, OrganizationUserUpdateParams data, ObjectMap params) throws ClientException { + params = params != null ? params : new ObjectMap(); + params.put("body", data); + return execute("organizations", null, "user", user, "update", params, POST, User.class); + } + /** * Return the organization information. * @param organization Organization id. diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java index 23b5a0f0afd..dd38bef63f4 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/ProjectClient.java @@ -31,7 +31,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -40,7 +40,7 @@ /** * This class contains methods for the Project webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: projects */ public class ProjectClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java index 5f69fa0997a..6b0e6027146 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/SampleClient.java @@ -35,7 +35,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -44,7 +44,7 @@ /** * This class contains methods for the Sample webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: samples */ public class SampleClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java index 02383dedf92..b6efa133f74 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/StudyClient.java @@ -47,7 +47,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -56,7 +56,7 @@ /** * This class contains methods for the Study webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: studies */ public class StudyClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java index bdadc50c29b..71da3473d79 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/UserClient.java @@ -36,7 +36,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -45,7 +45,7 @@ /** * This class contains methods for the User webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: users */ public class UserClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java index 58f15654b8d..4f6bfc3c603 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantClient.java @@ -62,7 +62,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -71,7 +71,7 @@ /** * This class contains methods for the Variant webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: analysis/variant */ public class VariantClient extends AbstractParentClient { diff --git a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java index 31b832fd1bd..b403abdd5da 100644 --- a/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java +++ b/opencga-client/src/main/java/org/opencb/opencga/client/rest/clients/VariantOperationClient.java @@ -50,7 +50,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. -* Autogenerated on: 2024-04-29 +* Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -59,7 +59,7 @@ /** * This class contains methods for the VariantOperation webservices. - * Client version: 3.1.0-SNAPSHOT + * Client version: 3.2.0-SNAPSHOT * PATH: operation */ public class VariantOperationClient extends AbstractParentClient { diff --git a/opencga-client/src/main/javascript/Admin.js b/opencga-client/src/main/javascript/Admin.js index 7fcab038434..6d42c5646f9 100644 --- a/opencga-client/src/main/javascript/Admin.js +++ b/opencga-client/src/main/javascript/Admin.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Alignment.js b/opencga-client/src/main/javascript/Alignment.js index 1ec703a5d46..0c5d7cfeb7d 100644 --- a/opencga-client/src/main/javascript/Alignment.js +++ b/opencga-client/src/main/javascript/Alignment.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/ClinicalAnalysis.js b/opencga-client/src/main/javascript/ClinicalAnalysis.js index e445a613946..25c6cd4c411 100644 --- a/opencga-client/src/main/javascript/ClinicalAnalysis.js +++ b/opencga-client/src/main/javascript/ClinicalAnalysis.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Cohort.js b/opencga-client/src/main/javascript/Cohort.js index 6f9ac1e3c22..1d9d146d8a4 100644 --- a/opencga-client/src/main/javascript/Cohort.js +++ b/opencga-client/src/main/javascript/Cohort.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/DiseasePanel.js b/opencga-client/src/main/javascript/DiseasePanel.js index 4343bc420dc..b034b4a06ea 100644 --- a/opencga-client/src/main/javascript/DiseasePanel.js +++ b/opencga-client/src/main/javascript/DiseasePanel.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Family.js b/opencga-client/src/main/javascript/Family.js index 245c24abe04..196bb81472b 100644 --- a/opencga-client/src/main/javascript/Family.js +++ b/opencga-client/src/main/javascript/Family.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/File.js b/opencga-client/src/main/javascript/File.js index 0a085be817c..2c4acdbd28a 100644 --- a/opencga-client/src/main/javascript/File.js +++ b/opencga-client/src/main/javascript/File.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/GA4GH.js b/opencga-client/src/main/javascript/GA4GH.js index 1bef974d359..f4d6eef054f 100644 --- a/opencga-client/src/main/javascript/GA4GH.js +++ b/opencga-client/src/main/javascript/GA4GH.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Individual.js b/opencga-client/src/main/javascript/Individual.js index ce94d506024..1744c4611ad 100644 --- a/opencga-client/src/main/javascript/Individual.js +++ b/opencga-client/src/main/javascript/Individual.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Job.js b/opencga-client/src/main/javascript/Job.js index 1d2aa95b0cc..a6ec63d51a5 100644 --- a/opencga-client/src/main/javascript/Job.js +++ b/opencga-client/src/main/javascript/Job.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Meta.js b/opencga-client/src/main/javascript/Meta.js index 6d9869452f1..599d48ecaaa 100644 --- a/opencga-client/src/main/javascript/Meta.js +++ b/opencga-client/src/main/javascript/Meta.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Organization.js b/opencga-client/src/main/javascript/Organization.js index a429ccf6868..176753b98cd 100644 --- a/opencga-client/src/main/javascript/Organization.js +++ b/opencga-client/src/main/javascript/Organization.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. @@ -103,6 +103,36 @@ export default class Organization extends OpenCGAParentClass { return this._post("organizations", null, "notes", id, "update", data, params); } + /** Update the user status + * @param {String} user - User ID. + * @param {Object} data - JSON containing the User fields to be updated. + * @param {Object} [params] - The Object containing the following optional parameters: + * @param {String} [params.include] - Fields included in the response, whole JSON path must be provided. + * @param {String} [params.exclude] - Fields excluded in the response, whole JSON path must be provided. + * @param {String} [params.organization] - Organization id. + * @param {Boolean} [params.includeResult = "false"] - Flag indicating to include the created or updated document result in the response. + * The default value is false. + * @returns {Promise} Promise object in the form of RestResponse instance. + */ + userUpdateStatus(user, data, params) { + return this._post("organizations/user", user, "status", null, "update", data, params); + } + + /** Update the user information + * @param {String} user - User ID. + * @param {Object} data - JSON containing the User fields to be updated. + * @param {Object} [params] - The Object containing the following optional parameters: + * @param {String} [params.include] - Fields included in the response, whole JSON path must be provided. + * @param {String} [params.exclude] - Fields excluded in the response, whole JSON path must be provided. + * @param {String} [params.organization] - Organization id. + * @param {Boolean} [params.includeResult = "false"] - Flag indicating to include the created or updated document result in the response. + * The default value is false. + * @returns {Promise} Promise object in the form of RestResponse instance. + */ + updateUser(user, data, params) { + return this._post("organizations", null, "user", user, "update", data, params); + } + /** Return the organization information * @param {String} organization - Organization id. * @param {Object} [params] - The Object containing the following optional parameters: diff --git a/opencga-client/src/main/javascript/Project.js b/opencga-client/src/main/javascript/Project.js index e58af550ded..1aa374428c2 100644 --- a/opencga-client/src/main/javascript/Project.js +++ b/opencga-client/src/main/javascript/Project.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Sample.js b/opencga-client/src/main/javascript/Sample.js index f4ae4e29625..2150b03db41 100644 --- a/opencga-client/src/main/javascript/Sample.js +++ b/opencga-client/src/main/javascript/Sample.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Study.js b/opencga-client/src/main/javascript/Study.js index d13f1d427c3..a144ce485e7 100644 --- a/opencga-client/src/main/javascript/Study.js +++ b/opencga-client/src/main/javascript/Study.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/User.js b/opencga-client/src/main/javascript/User.js index e478e03db6f..b4cd4245577 100644 --- a/opencga-client/src/main/javascript/User.js +++ b/opencga-client/src/main/javascript/User.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/Variant.js b/opencga-client/src/main/javascript/Variant.js index c341d110c64..7d165e13c9b 100644 --- a/opencga-client/src/main/javascript/Variant.js +++ b/opencga-client/src/main/javascript/Variant.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/javascript/VariantOperation.js b/opencga-client/src/main/javascript/VariantOperation.js index a178fbbddcf..8a616734c8f 100644 --- a/opencga-client/src/main/javascript/VariantOperation.js +++ b/opencga-client/src/main/javascript/VariantOperation.js @@ -12,7 +12,7 @@ * WARNING: AUTOGENERATED CODE * * This code was generated by a tool. - * Autogenerated on: 2024-04-29 + * Autogenerated on: 2024-05-24 * * Manual changes to this file may cause unexpected behavior in your application. * Manual changes to this file will be overwritten if the code is regenerated. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py index ead2235886b..f8ebdba7343 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/admin_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Admin(_ParentRestClient): """ This class contains methods for the 'Admin' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/admin """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py index 313d3223ade..7b2758e6e37 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/alignment_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Alignment(_ParentRestClient): """ This class contains methods for the 'Analysis - Alignment' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/analysis/alignment """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py index d43bfa65210..84f5ea24f2d 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/clinical_analysis_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class ClinicalAnalysis(_ParentRestClient): """ This class contains methods for the 'Analysis - Clinical' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/analysis/clinical """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py index 5772cf02ee5..eb7ec4bcaf7 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/cohort_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Cohort(_ParentRestClient): """ This class contains methods for the 'Cohorts' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/cohorts """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py index 0688b1f4c07..795d333fa6d 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/disease_panel_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class DiseasePanel(_ParentRestClient): """ This class contains methods for the 'Disease Panels' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/panels """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py index e13a27bddf0..7fbde777e75 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/family_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Family(_ParentRestClient): """ This class contains methods for the 'Families' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/families """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py index 0d9c9655f4b..f3dd1bf9fd0 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/file_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class File(_ParentRestClient): """ This class contains methods for the 'Files' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/files """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py index c7e9bb9efeb..1c4bcb2622a 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/ga4gh_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class GA4GH(_ParentRestClient): """ This class contains methods for the 'GA4GH' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/ga4gh """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py index a3c184edacd..3bdfd7154b8 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/individual_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Individual(_ParentRestClient): """ This class contains methods for the 'Individuals' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/individuals """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py index 22d31ddfacd..1e1c3322a5e 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/job_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Job(_ParentRestClient): """ This class contains methods for the 'Jobs' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/jobs """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py index 130fa0aa824..1d20a3ad0af 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/meta_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Meta(_ParentRestClient): """ This class contains methods for the 'Meta' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/meta """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/organization_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/organization_client.py index 681e988c54d..239155aa415 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/organization_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/organization_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Organization(_ParentRestClient): """ This class contains methods for the 'Organizations' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/organizations """ @@ -112,6 +112,44 @@ def update_notes(self, id, data=None, **options): return self._post(category='organizations', resource='update', subcategory='notes', second_query_id=id, data=data, **options) + def user_update_status(self, user, data=None, **options): + """ + Update the user status. + PATH: /{apiVersion}/organizations/user/{user}/status/update + + :param dict data: JSON containing the User fields to be updated. + (REQUIRED) + :param str user: User ID. (REQUIRED) + :param str include: Fields included in the response, whole JSON path + must be provided. + :param str exclude: Fields excluded in the response, whole JSON path + must be provided. + :param str organization: Organization id. + :param bool include_result: Flag indicating to include the created or + updated document result in the response. + """ + + return self._post(category='organizations/user', resource='update', query_id=user, subcategory='status', data=data, **options) + + def update_user(self, user, data=None, **options): + """ + Update the user information. + PATH: /{apiVersion}/organizations/user/{user}/update + + :param dict data: JSON containing the User fields to be updated. + (REQUIRED) + :param str user: User ID. (REQUIRED) + :param str include: Fields included in the response, whole JSON path + must be provided. + :param str exclude: Fields excluded in the response, whole JSON path + must be provided. + :param str organization: Organization id. + :param bool include_result: Flag indicating to include the created or + updated document result in the response. + """ + + return self._post(category='organizations', resource='update', subcategory='user', second_query_id=user, data=data, **options) + def info(self, organization, **options): """ Return the organization information. diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py index 28bf4f3e914..53c77a79c39 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/project_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Project(_ParentRestClient): """ This class contains methods for the 'Projects' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/projects """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py index 8f6753319e5..aeeb368c9e0 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/sample_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Sample(_ParentRestClient): """ This class contains methods for the 'Samples' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/samples """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py index b6f496bf061..56f37d203f8 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/study_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Study(_ParentRestClient): """ This class contains methods for the 'Studies' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/studies """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py index 6bc479ff5f0..3887175ea39 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/user_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class User(_ParentRestClient): """ This class contains methods for the 'Users' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/users """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py index db47d5553a7..10e5b69f9fa 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class Variant(_ParentRestClient): """ This class contains methods for the 'Analysis - Variant' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/analysis/variant """ diff --git a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py index ffaa0dbb2e4..b86475f2abc 100644 --- a/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py +++ b/opencga-client/src/main/python/pyopencga/rest_clients/variant_operation_client.py @@ -2,7 +2,7 @@ WARNING: AUTOGENERATED CODE This code was generated by a tool. - Autogenerated on: 2024-04-29 + Autogenerated on: 2024-05-24 Manual changes to this file may cause unexpected behavior in your application. Manual changes to this file will be overwritten if the code is regenerated. @@ -14,7 +14,7 @@ class VariantOperation(_ParentRestClient): """ This class contains methods for the 'Operations - Variant Storage' webservices - Client version: 3.1.0-SNAPSHOT + Client version: 3.2.0-SNAPSHOT PATH: /{apiVersion}/operation """ From a6485b642e84e0d7cbb658779d24c70d6411afe6 Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 25 Jun 2024 17:25:45 +0200 Subject: [PATCH 18/20] catalog: ensure new installs have a secretKey, #TASK-6013 --- .../opencga/catalog/managers/CatalogManager.java | 5 +++++ .../opencga/catalog/managers/OrganizationManager.java | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java index dd0e97eaf13..2ba352ee111 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java @@ -20,6 +20,7 @@ import org.opencb.commons.datastore.core.ObjectMap; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.catalog.auth.authentication.CatalogAuthenticationManager; +import org.opencb.opencga.catalog.auth.authentication.JwtManager; import org.opencb.opencga.catalog.auth.authentication.azure.AuthenticationFactory; import org.opencb.opencga.catalog.auth.authorization.AuthorizationDBAdaptorFactory; import org.opencb.opencga.catalog.auth.authorization.AuthorizationManager; @@ -260,6 +261,10 @@ private void privateInstall(String algorithm, String secretKey, String password, if (!PasswordUtils.isStrongPassword(password)) { throw new CatalogException("Invalid password. Check password strength for user "); } + if (StringUtils.isEmpty(secretKey)) { + logger.info("Generating secret key"); + secretKey = PasswordUtils.getStrongRandomPassword(JwtManager.SECRET_KEY_MIN_LENGTH); + } ParamUtils.checkParameter(secretKey, "secretKey"); ParamUtils.checkParameter(password, "password"); JwtUtils.validateJWTKey(algorithm, secretKey); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java index d487d4591f0..7a215219fd6 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/OrganizationManager.java @@ -25,6 +25,7 @@ import org.opencb.opencga.core.common.TimeUtils; import org.opencb.opencga.core.config.AuthenticationOrigin; import org.opencb.opencga.core.config.Configuration; +import org.opencb.opencga.core.config.Optimizations; import org.opencb.opencga.core.models.JwtPayload; import org.opencb.opencga.core.models.audit.AuditRecord; import org.opencb.opencga.core.models.common.Enums; @@ -394,6 +395,12 @@ private void validateOrganizationForCreation(Organization organization, String u if (organization.getConfiguration() == null) { organization.setConfiguration(new OrganizationConfiguration()); } + validateOrganizationConfiguration(organization); + + organization.setAttributes(ParamUtils.defaultObject(organization.getAttributes(), HashMap::new)); + } + + private void validateOrganizationConfiguration(Organization organization) throws CatalogParameterException { if (CollectionUtils.isNotEmpty(organization.getConfiguration().getAuthenticationOrigins())) { for (AuthenticationOrigin authenticationOrigin : organization.getConfiguration().getAuthenticationOrigins()) { ParamUtils.checkParameter(authenticationOrigin.getId(), "AuthenticationOrigin id"); @@ -409,7 +416,9 @@ private void validateOrganizationForCreation(Organization organization, String u } organization.getConfiguration().setDefaultUserExpirationDate(ParamUtils.defaultString( organization.getConfiguration().getDefaultUserExpirationDate(), Constants.DEFAULT_USER_EXPIRATION_DATE)); - organization.setAttributes(ParamUtils.defaultObject(organization.getAttributes(), HashMap::new)); + if (organization.getConfiguration().getOptimizations() == null) { + organization.getConfiguration().setOptimizations(new Optimizations(false)); + } } Set getOrganizationOwnerAndAdmins(String organizationId) throws CatalogException { From b57c260ba7355d16e071de599b8f74000d52cd54 Mon Sep 17 00:00:00 2001 From: pfurio Date: Tue, 2 Jul 2024 16:11:29 +0200 Subject: [PATCH 19/20] catalog: pass mail configuration to AuthFactory, #TASK-6013 --- .../authentication/azure/AuthenticationFactory.java | 12 ++++++------ .../opencga/catalog/managers/CatalogManager.java | 2 +- .../org/opencb/opencga/core/common/MailUtils.java | 4 ---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/azure/AuthenticationFactory.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/azure/AuthenticationFactory.java index d1b1246e468..378d200160c 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/azure/AuthenticationFactory.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/auth/authentication/azure/AuthenticationFactory.java @@ -11,7 +11,7 @@ import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.managers.OrganizationManager; import org.opencb.opencga.core.config.AuthenticationOrigin; -import org.opencb.opencga.core.config.Email; +import org.opencb.opencga.core.config.Configuration; import org.opencb.opencga.core.models.organizations.Organization; import org.opencb.opencga.core.models.user.AuthenticationResponse; import org.opencb.opencga.core.models.user.User; @@ -30,16 +30,15 @@ public final class AuthenticationFactory { private final Map> authenticationManagerMap; private final Logger logger = LoggerFactory.getLogger(AuthenticationFactory.class); private final DBAdaptorFactory catalogDBAdaptorFactory; + private final Configuration configuration; - public AuthenticationFactory(DBAdaptorFactory catalogDBAdaptorFactory) { + public AuthenticationFactory(DBAdaptorFactory catalogDBAdaptorFactory, Configuration configuration) { this.catalogDBAdaptorFactory = catalogDBAdaptorFactory; + this.configuration = configuration; authenticationManagerMap = new ConcurrentHashMap<>(); } public void configureOrganizationAuthenticationManager(Organization organization) throws CatalogException { - // TODO: Pass proper email values - Email email = new Email(); - Map tmpAuthenticationManagerMap = new HashMap<>(); long expiration = organization.getConfiguration().getToken().getExpiration(); @@ -60,7 +59,8 @@ public void configureOrganizationAuthenticationManager(Organization organization break; case OPENCGA: CatalogAuthenticationManager catalogAuthenticationManager = - new CatalogAuthenticationManager(catalogDBAdaptorFactory, email, algorithm, secretKey, expiration); + new CatalogAuthenticationManager(catalogDBAdaptorFactory, configuration.getEmail(), algorithm, + secretKey, expiration); tmpAuthenticationManagerMap.put(CatalogAuthenticationManager.INTERNAL, catalogAuthenticationManager); tmpAuthenticationManagerMap.put(CatalogAuthenticationManager.OPENCGA, catalogAuthenticationManager); break; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java index 2ba352ee111..1a23e5b1320 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/managers/CatalogManager.java @@ -109,7 +109,7 @@ private void init() throws CatalogException { catalogDBAdaptorFactory = new MongoDBAdaptorFactory(configuration, ioManagerFactory); authorizationDBAdaptorFactory = new AuthorizationMongoDBAdaptorFactory((MongoDBAdaptorFactory) catalogDBAdaptorFactory, configuration); - authenticationFactory = new AuthenticationFactory(catalogDBAdaptorFactory); + authenticationFactory = new AuthenticationFactory(catalogDBAdaptorFactory, configuration); logger.debug("CatalogManager configureManager"); configureManagers(configuration); } diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java index bf62bb7c09f..0a5a1ad4f9f 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/common/MailUtils.java @@ -16,8 +16,6 @@ package org.opencb.opencga.core.common; -import org.opencb.opencga.core.models.user.User; -import org.opencb.opencga.core.response.OpenCGAResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,8 +32,6 @@ public class MailUtils { private static final Logger logger = LoggerFactory.getLogger(MailUtils.class); - - public static void sendResetPasswordMail(String to, String newPassword, final String mailUser, final String mailPassword, String mailHost, String mailPort, String userId) throws Exception { From 978efa604fbd0c33145ec5480acaae6760a25b20 Mon Sep 17 00:00:00 2001 From: pfurio Date: Thu, 4 Jul 2024 11:02:51 +0200 Subject: [PATCH 20/20] catalog: use simplifyPermissions from Org configuration, #TASK-6013 --- .../mongodb/AuthorizationMongoDBAdaptor.java | 11 ++-- .../db/mongodb/AuthorizationMongoDBUtils.java | 53 ++++--------------- .../ClinicalAnalysisMongoDBAdaptor.java | 12 +++-- .../db/mongodb/CohortMongoDBAdaptor.java | 7 +-- .../db/mongodb/FamilyMongoDBAdaptor.java | 7 +-- .../db/mongodb/FileMongoDBAdaptor.java | 8 +-- .../db/mongodb/IndividualMongoDBAdaptor.java | 7 +-- .../catalog/db/mongodb/JobMongoDBAdaptor.java | 6 ++- .../catalog/db/mongodb/MongoDBAdaptor.java | 20 +++++++ .../db/mongodb/PanelMongoDBAdaptor.java | 5 +- .../db/mongodb/SampleMongoDBAdaptor.java | 7 +-- .../catalog/managers/CatalogManagerTest.java | 4 +- 12 files changed, 75 insertions(+), 72 deletions(-) diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBAdaptor.java index f7896320d10..445c1c6047a 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBAdaptor.java @@ -259,8 +259,9 @@ public List effectivePermissions(long studyUid, List resourceIdList } Document studyDocument = studyResult.first(); + boolean simplifyPermissions = simplifyPermissions(); Map> groupsMap = getGroupUsersMap(studyDocument); - Map> studyUserPermissionsMap = extractUserPermissionsMap(groupsMap, studyDocument); + Map> studyUserPermissionsMap = extractUserPermissionsMap(groupsMap, studyDocument, simplifyPermissions); // Retrieve ACL list for the resources requested MongoDBCollection collection = getMainCollection(entry); @@ -284,7 +285,8 @@ public List effectivePermissions(long studyUid, List resourceIdList throw new CatalogDBException("Resource id '" + resourceId + "' not found."); } Document resourceDocument = dataResultMap.get(resourceId); - Map> resourceUserPermissionsMap = extractUserPermissionsMap(groupsMap, resourceDocument); + Map> resourceUserPermissionsMap = extractUserPermissionsMap(groupsMap, resourceDocument, + simplifyPermissions); Acl acl = convertPermissionsToAcl(groupsMap, studyUserPermissionsMap, resourceUserPermissionsMap, resourceId, entry); aclList.add(acl); } @@ -357,7 +359,8 @@ private Acl convertPermissionsToAcl(Map> groupsMap, Map> extractUserPermissionsMap(Map> groupsMap, Document document) { + private Map> extractUserPermissionsMap(Map> groupsMap, Document document, + boolean simplifyPermissions) { Set allUsers = groupsMap.get(ParamConstants.MEMBERS_GROUP); // Map of userId - List of permissions @@ -383,8 +386,6 @@ private Map> extractUserPermissionsMap(Map userIdsWithPermissions = new HashSet<>(); // Personal ACLs diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBUtils.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBUtils.java index 987a493fd38..fb8a3952f50 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBUtils.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/AuthorizationMongoDBUtils.java @@ -25,7 +25,6 @@ import org.opencb.opencga.catalog.exceptions.CatalogDBException; import org.opencb.opencga.catalog.exceptions.CatalogParameterException; import org.opencb.opencga.core.api.ParamConstants; -import org.opencb.opencga.core.config.Configuration; import org.opencb.opencga.core.models.common.Enums; import org.opencb.opencga.core.models.study.StudyPermissions; @@ -200,35 +199,18 @@ private static int getPermissionType(Enums.Resource resource) throws CatalogPara /** * If query contains {@link ParamConstants#ACL_PARAM}, it will parse the value to generate the corresponding mongo query documents. * - * @param study Queried study document. - * @param query Original query. - * @param resource Affected resource. - * @param user User performing the query. - * @return A list of documents to satisfy the ACL query. - * @throws CatalogDBException when there is a DB error. - * @throws CatalogParameterException if there is any formatting error. - * @throws CatalogAuthorizationException if the user is not authorised to perform the query. - */ - public static List parseAclQuery(Document study, Query query, Enums.Resource resource, String user) - throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { - return parseAclQuery(study, query, resource, user, null); - } - - /** - * If query contains {@link ParamConstants#ACL_PARAM}, it will parse the value to generate the corresponding mongo query documents. - * - * @param study Queried study document. - * @param query Original query. - * @param resource Affected resource. - * @param user User performing the query. - * @param configuration Configuration object. + * @param study Queried study document. + * @param query Original query. + * @param resource Affected resource. + * @param user User performing the query. + * @param simplifyPermissions Boolean indicating whether permission check can be simplified. * @return A list of documents to satisfy the ACL query. * @throws CatalogDBException when there is a DB error. * @throws CatalogParameterException if there is any formatting error. * @throws CatalogAuthorizationException if the user is not authorised to perform the query. */ public static List parseAclQuery(Document study, Query query, Enums.Resource resource, String user, - Configuration configuration) + boolean simplifyPermissions) throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException { List aclDocuments = new LinkedList<>(); if (!query.containsKey(ParamConstants.ACL_PARAM)) { @@ -264,11 +246,6 @@ public static List parseAclQuery(Document study, Query query, Enums.Re + study.getString(StudyDBAdaptor.QueryParams.ID.key())); } - boolean simplifyPermissionCheck = false; - if (configuration != null && configuration.getOptimizations() != null) { - simplifyPermissionCheck = configuration.getOptimizations().isSimplifyPermissions(); - } - boolean isAnonymousPresent = false; boolean isRegisteredUsersPresent = false; List groups; @@ -302,7 +279,7 @@ public static List parseAclQuery(Document study, Query query, Enums.Re } Document queryDocument = getAuthorisedEntries(affectedUser, groups, permission, isRegisteredUsersPresent, isAnonymousPresent, - simplifyPermissionCheck); + simplifyPermissions); if (hasStudyPermissions) { // The user has permissions defined globally, so we also have to check the entries where the user/groups/members/* have no // permissions defined as the user will also be allowed to see them @@ -317,13 +294,8 @@ public static List parseAclQuery(Document study, Query query, Enums.Re return aclDocuments; } - public static Document getQueryForAuthorisedEntries(Document study, String user, String permission, Enums.Resource resource) - throws CatalogAuthorizationException, CatalogParameterException { - return getQueryForAuthorisedEntries(study, user, permission, resource, null); - } - public static Document getQueryForAuthorisedEntries(Document study, String user, String permission, Enums.Resource resource, - Configuration configuration) + boolean simplifyPermissions) throws CatalogAuthorizationException, CatalogParameterException { if (StringUtils.isEmpty(user)) { return new Document(); @@ -342,11 +314,6 @@ public static Document getQueryForAuthorisedEntries(Document study, String user, + study.getString(StudyDBAdaptor.QueryParams.ID.key())); } - boolean simplifyPermissionCheck = false; - if (configuration != null && configuration.getOptimizations() != null) { - simplifyPermissionCheck = configuration.getOptimizations().isSimplifyPermissions(); - } - String studyPermission = StudyPermissions.Permissions.getStudyPermission(permission, getPermissionType(resource)).name(); // 0. Check if anonymous has any permission defined (just for performance) @@ -375,8 +342,8 @@ public static Document getQueryForAuthorisedEntries(Document study, String user, } Document queryDocument = getAuthorisedEntries(user, groups, permission, isRegisteredUsersPresent, isAnonymousPresent, - simplifyPermissionCheck); - if (hasStudyPermissions && !simplifyPermissionCheck) { + simplifyPermissions); + if (hasStudyPermissions && !simplifyPermissions) { // The user has permissions defined globally, so we also have to check the entries where the user/groups/members/* have no // permissions defined as the user will also be allowed to see them queryDocument = new Document("$or", Arrays.asList( diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java index a2c4848fca1..ec066ba4fc6 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/ClinicalAnalysisMongoDBAdaptor.java @@ -31,7 +31,10 @@ import org.opencb.commons.datastore.core.*; import org.opencb.commons.datastore.mongodb.MongoDBCollection; import org.opencb.commons.datastore.mongodb.MongoDBIterator; -import org.opencb.opencga.catalog.db.api.*; +import org.opencb.opencga.catalog.db.api.ClinicalAnalysisDBAdaptor; +import org.opencb.opencga.catalog.db.api.DBIterator; +import org.opencb.opencga.catalog.db.api.FileDBAdaptor; +import org.opencb.opencga.catalog.db.api.InterpretationDBAdaptor; import org.opencb.opencga.catalog.db.mongodb.converters.ClinicalAnalysisConverter; import org.opencb.opencga.catalog.db.mongodb.iterators.ClinicalAnalysisCatalogMongoDBIterator; import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException; @@ -1313,17 +1316,18 @@ private Bson parseQuery(Query query, Document extraQuery, String user) if (queryCopy.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || queryCopy.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, queryCopy.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (queryCopy.containsKey(ParamConstants.ACL_PARAM)) { andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, queryCopy, Enums.Resource.CLINICAL_ANALYSIS, user, - configuration)); + simplifyPermissions)); } else { if (containsAnnotationQuery(query)) { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, - ClinicalAnalysisPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.CLINICAL_ANALYSIS, configuration)); + ClinicalAnalysisPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.CLINICAL_ANALYSIS, simplifyPermissions)); } else { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, ClinicalAnalysisPermissions.VIEW.name(), - Enums.Resource.CLINICAL_ANALYSIS, configuration)); + Enums.Resource.CLINICAL_ANALYSIS, simplifyPermissions)); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java index c6dd04863de..f34f5ced849 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/CohortMongoDBAdaptor.java @@ -879,18 +879,19 @@ private Bson parseQuery(Query query, Document extraQuery, String user) if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { + boolean simplifyPermissions = simplifyPermissions(); Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); if (query.containsKey(ParamConstants.ACL_PARAM)) { andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.COHORT, user, - configuration)); + simplifyPermissions)); } else { if (containsAnnotationQuery(query)) { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, - CohortPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.COHORT, configuration)); + CohortPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.COHORT, simplifyPermissions)); } else { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, CohortPermissions.VIEW.name(), - Enums.Resource.COHORT, configuration)); + Enums.Resource.COHORT, simplifyPermissions)); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java index 2b7ed748772..9e8c35d00ab 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FamilyMongoDBAdaptor.java @@ -1191,17 +1191,18 @@ protected Bson parseQuery(Query query, Document extraQuery, String user) if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (query.containsKey(ParamConstants.ACL_PARAM)) { andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.FAMILY, user, - configuration)); + simplifyPermissions)); } else { if (containsAnnotationQuery(query)) { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, - FamilyPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.FAMILY, configuration)); + FamilyPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.FAMILY, simplifyPermissions)); } else { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, FamilyPermissions.VIEW.name(), - Enums.Resource.FAMILY, configuration)); + Enums.Resource.FAMILY, simplifyPermissions)); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java index 5b84d050083..f214620bf39 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/FileMongoDBAdaptor.java @@ -1409,16 +1409,18 @@ private Bson parseQuery(Query query, Document extraQuery, String user) if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (query.containsKey(ParamConstants.ACL_PARAM)) { - andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.FILE, user, configuration)); + andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.FILE, user, + simplifyPermissions)); } else { if (containsAnnotationQuery(query)) { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, FilePermissions.VIEW_ANNOTATIONS.name(), - Enums.Resource.FILE, configuration)); + Enums.Resource.FILE, simplifyPermissions)); } else { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, FilePermissions.VIEW.name(), - Enums.Resource.FILE, configuration)); + Enums.Resource.FILE, simplifyPermissions)); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java index 707375a5811..13dbb40741c 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/IndividualMongoDBAdaptor.java @@ -1405,17 +1405,18 @@ private Bson parseQuery(Query query, Document extraQuery, String user) if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (query.containsKey(ParamConstants.ACL_PARAM)) { andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.INDIVIDUAL, user, - configuration)); + simplifyPermissions)); } else { if (containsAnnotationQuery(query)) { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, - IndividualPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.INDIVIDUAL, configuration)); + IndividualPermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.INDIVIDUAL, simplifyPermissions)); } else { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, IndividualPermissions.VIEW.name(), - Enums.Resource.INDIVIDUAL, configuration)); + Enums.Resource.INDIVIDUAL, simplifyPermissions)); } } diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java index 58b3291a0d4..e193c5b9e09 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/JobMongoDBAdaptor.java @@ -814,13 +814,15 @@ private Bson parseQuery(Query query, Document extraQuery, QueryOptions options, if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (query.containsKey(ParamConstants.ACL_PARAM)) { - andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.JOB, user, configuration)); + andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.JOB, user, + simplifyPermissions)); } else { // Get the document query needed to check the permissions as well andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, JobPermissions.VIEW.name(), - Enums.Resource.JOB, configuration)); + Enums.Resource.JOB, simplifyPermissions)); } query.remove(ParamConstants.ACL_PARAM); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java index 0b6f07d4269..7f41e38411d 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/MongoDBAdaptor.java @@ -28,10 +28,12 @@ import org.opencb.opencga.catalog.db.AbstractDBAdaptor; import org.opencb.opencga.catalog.db.api.StudyDBAdaptor; import org.opencb.opencga.catalog.exceptions.*; +import org.opencb.opencga.catalog.managers.OrganizationManager; import org.opencb.opencga.catalog.utils.Constants; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.config.Configuration; +import org.opencb.opencga.core.models.organizations.Organization; import org.opencb.opencga.core.response.OpenCGAResult; import org.slf4j.Logger; @@ -703,6 +705,24 @@ protected Document getStudyDocument(ClientSession clientSession, long studyUid) return dataResult.first(); } + /** + * Method to obtain whether permissions should be simplified or not. + * + * @return true if permissions should be simplified, false otherwise. + * @throws CatalogDBException if there is any error obtaining the organization configuration. + */ + protected boolean simplifyPermissions() throws CatalogDBException { + Organization organization = dbAdaptorFactory.getCatalogOrganizationDBAdaptor() + .get(OrganizationManager.INCLUDE_ORGANIZATION_CONFIGURATION).first(); + if (organization.getConfiguration().getOptimizations() != null) { + return organization.getConfiguration().getOptimizations().isSimplifyPermissions(); + } else { + logger.warn("Organization '{}' configuration does not contain the 'optimizations.simplifyPermissions' field. Defaulting" + + " to false", organization.getId()); + return false; + } + } + public class NestedArrayUpdateDocument { private Query query; private Document set; diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java index d373c68bb2b..d82535b9351 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/PanelMongoDBAdaptor.java @@ -722,14 +722,15 @@ private Bson parseQuery(Query query, Document extraQuery, String user) if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (query.containsKey(ParamConstants.ACL_PARAM)) { andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.DISEASE_PANEL, user, - configuration)); + simplifyPermissions)); } else { // Get the document query needed to check the permissions as well andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, PanelPermissions.VIEW.name(), - Enums.Resource.DISEASE_PANEL, configuration)); + Enums.Resource.DISEASE_PANEL, simplifyPermissions)); } query.remove(ParamConstants.ACL_PARAM); diff --git a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java index a6d3b8521c0..198c9fce456 100644 --- a/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java +++ b/opencga-catalog/src/main/java/org/opencb/opencga/catalog/db/mongodb/SampleMongoDBAdaptor.java @@ -1327,17 +1327,18 @@ private Bson parseQuery(Query query, Document extraQuery, String user) if (query.containsKey(QueryParams.STUDY_UID.key()) && (StringUtils.isNotEmpty(user) || query.containsKey(ParamConstants.ACL_PARAM))) { Document studyDocument = getStudyDocument(null, query.getLong(QueryParams.STUDY_UID.key())); + boolean simplifyPermissions = simplifyPermissions(); if (query.containsKey(ParamConstants.ACL_PARAM)) { andBsonList.addAll(AuthorizationMongoDBUtils.parseAclQuery(studyDocument, query, Enums.Resource.SAMPLE, user, - configuration)); + simplifyPermissions)); } else { if (containsAnnotationQuery(query)) { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, - SamplePermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.SAMPLE, configuration)); + SamplePermissions.VIEW_ANNOTATIONS.name(), Enums.Resource.SAMPLE, simplifyPermissions)); } else { andBsonList.add(getQueryForAuthorisedEntries(studyDocument, user, SamplePermissions.VIEW.name(), - Enums.Resource.SAMPLE, configuration)); + Enums.Resource.SAMPLE, simplifyPermissions)); } } diff --git a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java index cb9244ae7d3..6345386e69f 100644 --- a/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java +++ b/opencga-catalog/src/test/java/org/opencb/opencga/catalog/managers/CatalogManagerTest.java @@ -37,6 +37,7 @@ import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.common.TimeUtils; +import org.opencb.opencga.core.config.Optimizations; import org.opencb.opencga.core.models.Acl; import org.opencb.opencga.core.models.AclEntry; import org.opencb.opencga.core.models.AclEntryList; @@ -49,6 +50,7 @@ import org.opencb.opencga.core.models.individual.Individual; import org.opencb.opencga.core.models.individual.IndividualUpdateParams; import org.opencb.opencga.core.models.job.*; +import org.opencb.opencga.core.models.organizations.OrganizationConfiguration; import org.opencb.opencga.core.models.organizations.OrganizationCreateParams; import org.opencb.opencga.core.models.organizations.OrganizationUpdateParams; import org.opencb.opencga.core.models.project.DataStore; @@ -2328,7 +2330,7 @@ public void getEffectivePermissions() throws CatalogException { Arrays.asList(orgOwnerUserId, orgAdminUserId1, orgAdminUserId2, studyAdminUserId1, normalUserId1, normalUserId2, normalUserId3, "user5", "user6", ParamConstants.ANONYMOUS_USER_ID), Arrays.asList("user4", "user7"), aclList.getResults().get(2)); - catalogManager.getConfiguration().getOptimizations().setSimplifyPermissions(true); + catalogManager.getOrganizationManager().updateConfiguration(organizationId, new OrganizationConfiguration().setOptimizations(new Optimizations(true)), null, ownerToken); aclList = catalogManager.getAdminManager().getEffectivePermissions(studyFqn, Arrays.asList(s_7Id, s_8Id, s_9Id), Enums.Resource.SAMPLE.name(), ownerToken); assertEquals(3, aclList.getNumResults()); assertPermissions(s_7Id, Arrays.asList(orgOwnerUserId, orgAdminUserId1, orgAdminUserId2, studyAdminUserId1, normalUserId1, normalUserId2, normalUserId3, "user4", "user5", "user6", "user7", ParamConstants.ANONYMOUS_USER_ID),