From fd0215c3fb18a1c5b516fe5764f6e7c090001369 Mon Sep 17 00:00:00 2001 From: Om Bhardwaj <115864495+OmBhardwajj@users.noreply.github.com> Date: Fri, 21 Jun 2024 15:42:47 +0530 Subject: [PATCH] avniproject#733 | Some refactoring changes,and fixed the permissions group error which was caused due to wrong code being pushed in my last commit --- .../dao/metabase/BaseMetabaseRepository.java | 44 ---------- .../CollectionPermissionsRepository.java | 35 ++++++++ .../dao/metabase/CollectionRepository.java | 10 +-- .../dao/metabase/DatabaseRepository.java | 10 +-- .../dao/metabase/MetabaseConnector.java | 63 ++++++++++++++ .../dao/metabase/MetabaseRepository.java | 53 ------------ .../metabase/PermissionsGroupRepository.java | 39 +++++++++ .../dao/metabase/PermissionsRepository.java | 4 - .../metabase/CollectionPermissions.java | 82 ++++++++++++++++--- .../CollectionPermissionsGraphResponse.java | 27 ++++++ .../domain/metabase/CollectionResponse.java | 3 + .../avni/server/domain/metabase/Database.java | 34 +++++++- .../domain/metabase/DatabaseDetails.java | 8 +- .../server/domain/metabase/Permissions.java | 41 ---------- .../metabase/PermissionsGraphResponse.java | 42 ++++++++++ .../domain/metabase/PermissionsGroup.java | 26 +++++- .../domain/metabase/PermissionsGroupBody.java | 28 +++++++ .../metabase/PermissionsGroupResponse.java | 13 --- .../metabase/PermissionsGroupService.java | 80 ++++++++++++++++++ .../avni/server/service/MetabaseService.java | 49 +++++++---- .../avni/server/web/MetabaseController.java | 9 +- .../src/main/resources/application.properties | 2 +- 22 files changed, 493 insertions(+), 209 deletions(-) delete mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/BaseMetabaseRepository.java create mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionPermissionsRepository.java create mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseConnector.java delete mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseRepository.java create mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsGroupRepository.java delete mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsRepository.java create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsGraphResponse.java delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/Permissions.java create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGraphResponse.java create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupBody.java delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupResponse.java create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupService.java diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/BaseMetabaseRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/BaseMetabaseRepository.java deleted file mode 100644 index 780989568..000000000 --- a/avni-server-api/src/main/java/org/avni/server/dao/metabase/BaseMetabaseRepository.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.avni.server.dao.metabase; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Repository; -import org.springframework.web.client.RestTemplate; - -import java.util.Map; - -@Repository -public class BaseMetabaseRepository { - protected final RestTemplate restTemplate; - - @Value("${metabase.api.url}") - protected String metabaseApiUrl; - - @Value("${metabase.api.key}") - private String apiKey; - - public BaseMetabaseRepository(RestTemplateBuilder restTemplateBuilder) { - this.restTemplate = restTemplateBuilder.build(); - } - - private HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - headers.set("x-api-key", apiKey); - return headers; - } - - protected HttpEntity createHttpEntity(T body) { - HttpHeaders headers = getHeaders(); - return new HttpEntity<>(body, headers); - } - - protected void sendPutRequest(String url, Map requestBody) { - HttpEntity> entity = createHttpEntity(requestBody); - restTemplate.exchange(url, HttpMethod.PUT, entity, Map.class); - } -} diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionPermissionsRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionPermissionsRepository.java new file mode 100644 index 000000000..47036f8c3 --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionPermissionsRepository.java @@ -0,0 +1,35 @@ +package org.avni.server.dao.metabase; + +import org.avni.server.domain.metabase.CollectionPermissions; +import org.avni.server.domain.metabase.CollectionPermissionsGraphResponse; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.Map; + +@Repository +public class CollectionPermissionsRepository extends MetabaseConnector { + + public CollectionPermissionsRepository(RestTemplateBuilder restTemplateBuilder) { + super(restTemplateBuilder); + } + + public CollectionPermissionsGraphResponse getCollectionPermissionsGraph() { + String url = metabaseApiUrl + "/collection/graph"; + return getForObject(url, CollectionPermissionsGraphResponse.class); + } + + public void updateCollectionPermissions(CollectionPermissions collectionPermissions, int groupId, int collectionId) { + collectionPermissions.updatePermissionsGraph(groupId, collectionId); + String url = metabaseApiUrl + "/collection/graph"; + sendPutRequest(url, convertToMap(collectionPermissions.getPermissionsGraph())); + } + + private Map convertToMap(CollectionPermissionsGraphResponse collectionPermissionsGraphResponse) { + Map map = new HashMap<>(); + map.put("revision", collectionPermissionsGraphResponse.getRevision()); + map.put("groups", collectionPermissionsGraphResponse.getGroups()); + return map; + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionRepository.java index 17d709e46..50c28e816 100644 --- a/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionRepository.java +++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionRepository.java @@ -3,18 +3,16 @@ import org.avni.server.domain.metabase.Collection; import org.avni.server.domain.metabase.CollectionResponse; import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpEntity; +import org.springframework.stereotype.Repository; -public class CollectionRepository extends MetabaseRepository{ +@Repository +public class CollectionRepository extends MetabaseConnector { public CollectionRepository(RestTemplateBuilder restTemplateBuilder) { super(restTemplateBuilder); } public CollectionResponse save(Collection collection) { String url = metabaseApiUrl + "/collection"; - HttpEntity entity = createHttpEntity(collection); - CollectionResponse response = restTemplate.postForObject(url, entity, CollectionResponse.class); - - return response; + return postForObject(url, collection, CollectionResponse.class); } } diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/DatabaseRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/DatabaseRepository.java index 3b5971829..bd06541b6 100644 --- a/avni-server-api/src/main/java/org/avni/server/dao/metabase/DatabaseRepository.java +++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/DatabaseRepository.java @@ -2,20 +2,18 @@ import org.avni.server.domain.metabase.Database; import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpEntity; import org.springframework.stereotype.Repository; @Repository -public class DatabaseRepository extends MetabaseRepository{ +public class DatabaseRepository extends MetabaseConnector { public DatabaseRepository(RestTemplateBuilder restTemplateBuilder) { super(restTemplateBuilder); } public Database save(Database database) { String url = metabaseApiUrl + "/database"; - HttpEntity entity = createHttpEntity(database); - Database response = restTemplate.postForObject(url, entity, Database.class); - - return new Database(response.getId(), database.getName(), database.getEngine(), database.getDetails()); + Database response = postForObject(url, database, Database.class); + database.setId(response.getId()); + return database; } } diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseConnector.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseConnector.java new file mode 100644 index 000000000..013208e43 --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseConnector.java @@ -0,0 +1,63 @@ +package org.avni.server.dao.metabase; + +import org.avni.server.domain.metabase.PermissionsGroup; +import org.avni.server.domain.metabase.PermissionsGroupBody; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Repository; +import org.springframework.web.client.RestTemplate; + +import java.util.Collections; +import java.util.Map; + +@Repository +public class MetabaseConnector { + protected final RestTemplate restTemplate; + + @Value("${metabase.api.url}") + protected String metabaseApiUrl; + + @Value("${metabase.api.key}") + private String apiKey; + + public MetabaseConnector(RestTemplateBuilder restTemplateBuilder) { + this.restTemplate = restTemplateBuilder.build(); + } + + protected HttpHeaders getHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set("x-api-key", apiKey); + return headers; + } + + protected HttpEntity createHttpEntity(T body) { + HttpHeaders headers = getHeaders(); + return new HttpEntity<>(body, headers); + } + + protected void sendPutRequest(String url, Map requestBody) { + HttpEntity> entity = createHttpEntity(requestBody); + restTemplate.exchange(url, HttpMethod.PUT, entity, Map.class); + } + + protected T postForObject(String url, Object request, Class responseType) { + HttpEntity entity = createHttpEntity(request); + return restTemplate.postForObject(url, entity, responseType); + } + + protected T getForObject(String url, Class responseType) { + HttpHeaders headers = getHeaders(); + HttpEntity entity = new HttpEntity<>(headers); + return restTemplate.exchange(url, HttpMethod.GET, entity, responseType).getBody(); + } + + protected HttpEntity> createJsonEntity(PermissionsGroupBody body) { + HttpHeaders headers = getHeaders(); + return new HttpEntity<>(body.getBody(), headers); + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseRepository.java deleted file mode 100644 index f0850a1e8..000000000 --- a/avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseRepository.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.avni.server.dao.metabase; - -import org.avni.server.domain.metabase.CollectionPermissions; -import org.avni.server.domain.metabase.Permissions; -import org.avni.server.domain.metabase.PermissionsGroup; -import org.avni.server.domain.metabase.PermissionsGroupResponse; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Repository; - -import java.util.Map; - -@Repository -public class MetabaseRepository extends BaseMetabaseRepository{ - - public MetabaseRepository(RestTemplateBuilder restTemplateBuilder) { - super(restTemplateBuilder); - } - - public PermissionsGroupResponse createPermissionsGroup(PermissionsGroup permissionsGroup) { - String url = metabaseApiUrl + "/permissions/group"; - HttpEntity entity = createHttpEntity(permissionsGroup); - PermissionsGroupResponse response = restTemplate.postForObject(url, entity, PermissionsGroupResponse.class); - - return response; - } - - public Map getPermissionsGraph() { - String url = metabaseApiUrl + "/permissions/graph"; - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, createHttpEntity(null), Map.class); - return response.getBody(); - } - - public Map getCollectionPermissionsGraph() { - String url = metabaseApiUrl + "/collection/graph"; - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, createHttpEntity(null), Map.class); - return response.getBody(); - } - - public void assignDatabasePermissions(Permissions permissions, int groupId, int databaseId) { - permissions.updatePermissionsGraph(groupId, databaseId); - String url = metabaseApiUrl + "/permissions/graph"; - sendPutRequest(url, permissions.getPermissionsGraph()); - } - - public void updateCollectionPermissions(CollectionPermissions collectionPermissions, int groupId, int collectionId) { - collectionPermissions.updatePermissionsGraph(groupId, collectionId); - String url = metabaseApiUrl + "/collection/graph"; - sendPutRequest(url, collectionPermissions.getPermissionsGraph()); - } -} diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsGroupRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsGroupRepository.java new file mode 100644 index 000000000..55d710fa2 --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsGroupRepository.java @@ -0,0 +1,39 @@ +package org.avni.server.dao.metabase; + +import org.avni.server.domain.metabase.PermissionsGroupService; +import org.avni.server.domain.metabase.PermissionsGraphResponse; +import org.avni.server.domain.metabase.PermissionsGroup; +import org.avni.server.domain.metabase.PermissionsGroupBody; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpEntity; +import org.springframework.stereotype.Repository; + +import java.util.Map; + +@Repository +public class PermissionsGroupRepository extends MetabaseConnector { + + public PermissionsGroupRepository(RestTemplateBuilder restTemplateBuilder) { + super(restTemplateBuilder); + } + + public PermissionsGroup save(PermissionsGroup permissionsGroup) { + String url = metabaseApiUrl + "/permissions/group"; + PermissionsGroupBody body = new PermissionsGroupBody(permissionsGroup.getName()); + HttpEntity> entity = createJsonEntity(body); + + PermissionsGroup response = restTemplate.postForObject(url, entity, PermissionsGroup.class); + return response; + } + + public PermissionsGraphResponse getPermissionsGraph() { + String url = metabaseApiUrl + "/permissions/graph"; + return getForObject(url, PermissionsGraphResponse.class); + } + + public void updatePermissionsGraph(PermissionsGroupService permissions, int groupId, int databaseId) { + String url = metabaseApiUrl + "/permissions/graph"; + Map requestBody = permissions.getUpdatedPermissionsGraph(); + sendPutRequest(url, requestBody); + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsRepository.java deleted file mode 100644 index 58e9fe476..000000000 --- a/avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsRepository.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.avni.server.dao.metabase; - -public class PermissionsRepository { -} diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissions.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissions.java index 963af0e23..8df4cf39c 100644 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissions.java +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissions.java @@ -3,27 +3,85 @@ import java.util.HashMap; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component public class CollectionPermissions { - private Map permissionsGraph; + private final CollectionPermissionsGraphResponse permissionsGraphResponse; - public CollectionPermissions(Map permissionsGraph) { - this.permissionsGraph = permissionsGraph; + @Autowired + public CollectionPermissions(CollectionPermissionsGraphResponse permissionsGraphResponse) { + this.permissionsGraphResponse = permissionsGraphResponse; } - public Map getPermissionsGraph() { - return permissionsGraph; + /** + * Update the permissions graph to add write access for a specific group and collection. + * + * @param groupId the ID of the group + * @param collectionId the ID of the collection + */ + public void updatePermissionsGraph(int groupId, int collectionId) { + Map> groupsMap = permissionsGraphResponse.getGroups(); + ensureGroupsMapExists(groupsMap); + + Map groupPermissions = getOrCreateGroupPermissions(groupsMap, groupId); + updateGroupPermissions(groupPermissions, collectionId); + + handleSpecialGroupPermissions(groupsMap, collectionId); } - public void updatePermissionsGraph(int groupId, int collectionId) { - Map> groups = (Map>) permissionsGraph.get("groups"); + /** + * Ensure the groups map exists, throw an exception if it does not. + * + * @param groupsMap the map of groups + */ + private void ensureGroupsMapExists(Map> groupsMap) { + if (groupsMap == null) { + throw new RuntimeException("Groups not found in the collection permissions graph."); + } + } + + /** + * Get the permissions map for a specific group, create it if it does not exist. + * + * @param groupsMap the map of all groups + * @param groupId the ID of the group + * @return the permissions map for the specified group + */ + private Map getOrCreateGroupPermissions(Map> groupsMap, int groupId) { + return groupsMap.computeIfAbsent(String.valueOf(groupId), k -> new HashMap<>()); + } - groups.computeIfAbsent(String.valueOf(groupId), k -> new HashMap<>()); - Map groupPermissions = groups.get(String.valueOf(groupId)); + /** + * Update the permissions for a specific collection in a group. + * + * @param groupPermissions the map of permissions for a group + * @param collectionId the ID of the collection + */ + private void updateGroupPermissions(Map groupPermissions, int collectionId) { groupPermissions.put(String.valueOf(collectionId), "write"); + } - if (groups.containsKey("1")) { - Map allGroupPermissions = groups.get("1"); - allGroupPermissions.put(String.valueOf(collectionId), "none"); + /** + * Handle the special case for group with ID "1", setting its permission for the collection to "none". + * + * @param groupsMap the map of all groups + * @param collectionId the ID of the collection + */ + private void handleSpecialGroupPermissions(Map> groupsMap, int collectionId) { + if (groupsMap.containsKey("1")) { + Map group1Permissions = groupsMap.get("1"); + group1Permissions.put(String.valueOf(collectionId), "none"); } } + + /** + * Get the permissions graph response. + * + * @return the permissions graph response + */ + public CollectionPermissionsGraphResponse getPermissionsGraph() { + return permissionsGraphResponse; + } } diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsGraphResponse.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsGraphResponse.java new file mode 100644 index 000000000..7ce886b82 --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsGraphResponse.java @@ -0,0 +1,27 @@ +package org.avni.server.domain.metabase; + +import java.util.Map; + +import org.springframework.stereotype.Component; + +@Component +public class CollectionPermissionsGraphResponse { + private int revision; + private Map> groups; + + public int getRevision() { + return revision; + } + + public void setRevision(int revision) { + this.revision = revision; + } + + public Map> getGroups() { + return groups; + } + + public void setGroups(Map> groups) { + this.groups = groups; + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionResponse.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionResponse.java index 3446978f6..6b58d6c36 100644 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionResponse.java +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionResponse.java @@ -1,5 +1,8 @@ package org.avni.server.domain.metabase; +import org.springframework.stereotype.Component; + +@Component public class CollectionResponse { private int id; diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Database.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/Database.java index 82e4fd36e..0bf1af408 100644 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Database.java +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/Database.java @@ -1,17 +1,24 @@ package org.avni.server.domain.metabase; +import org.springframework.stereotype.Component; + +@Component public class Database { - private final Integer id; + private Integer id; private String name; private String engine; private DatabaseDetails details; + + public Database() { + } + public Database(String name, String engine, DatabaseDetails details) { - this(null, name, engine, details); + this(null,name,engine,details); } - public Database(Integer id, String name, String engine, DatabaseDetails details) { - this.id = id; + public Database(Integer id,String name, String engine, DatabaseDetails details) { + this.id=id; this.name = name; this.engine = engine; this.details = details; @@ -20,15 +27,34 @@ public Database(Integer id, String name, String engine, DatabaseDetails details) public Integer getId() { return id; } + + public void setId(Integer id) { + this.id = id; + } + public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + public String getEngine() { return engine; } + public void setEngine(String engine) { + this.engine = engine; + } + public DatabaseDetails getDetails() { return details; } + + public void setDetails(DatabaseDetails details) { + this.details = details; + } + + } diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/DatabaseDetails.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/DatabaseDetails.java index 9950d988a..416f7bae6 100644 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/DatabaseDetails.java +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/DatabaseDetails.java @@ -1,11 +1,17 @@ package org.avni.server.domain.metabase; +import org.springframework.stereotype.Component; + +@Component public class DatabaseDetails { private String host; private String port; private String db; private String user; + public DatabaseDetails() { + } + public DatabaseDetails(String host, String port, String db, String user) { this.host = host; this.port = port; @@ -32,6 +38,4 @@ public String getDb() { public String getUser() { return user; } - - } diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Permissions.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/Permissions.java deleted file mode 100644 index b9668f824..000000000 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Permissions.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.avni.server.domain.metabase; - -import java.util.HashMap; -import java.util.Map; - -public class Permissions { - private Map permissionsGraph; - - public Permissions(Map permissionsGraph) { - this.permissionsGraph = permissionsGraph; - } - - public Map getPermissionsGraph() { - return permissionsGraph; - } - - public void updatePermissionsGraph(int groupId, int databaseId) { - Map groups = (Map) permissionsGraph.get("groups"); - - Map databasePermissions = new HashMap<>(); - databasePermissions.put("data", new HashMap() {{ - put("schemas", "all"); - }}); - - groups.computeIfAbsent(String.valueOf(groupId), k -> new HashMap<>()); - Map groupPermissions = (Map) groups.get(String.valueOf(groupId)); - groupPermissions.put(String.valueOf(databaseId), databasePermissions); - - if (groups.containsKey("1")) { - Map allGroupsPermissionsMap = (Map) groups.get("1"); - if (allGroupsPermissionsMap.containsKey(String.valueOf(databaseId))) { - Map allGroupsDatabasePermissions = (Map) allGroupsPermissionsMap.get(String.valueOf(databaseId)); - if (allGroupsDatabasePermissions.containsKey("data")) { - Map dataPermissions = (Map) allGroupsDatabasePermissions.get("data"); - dataPermissions.put("native", "none"); - dataPermissions.put("schemas", "none"); - } - } - } - } -} \ No newline at end of file diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGraphResponse.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGraphResponse.java new file mode 100644 index 000000000..12335f31b --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGraphResponse.java @@ -0,0 +1,42 @@ +package org.avni.server.domain.metabase; + +import java.util.Map; + +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@Component +@JsonIgnoreProperties(ignoreUnknown = true) +public class PermissionsGraphResponse { + @JsonProperty("groups") + private Map groups; + + @JsonProperty("revision") + private int revision; + + public Map getGroups() { + return groups; + } + + public void setGroups(Map groups) { + this.groups = groups; + } + + public int getRevision() { + return revision; + } + + public void setRevision(int revision) { + this.revision = revision; + } + + @Override + public String toString() { + return "PermissionsGraphResponse{" + + "groups=" + groups + + ", revision=" + revision + + '}'; + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java index b4b1e9003..d1a2f724b 100644 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java @@ -2,12 +2,32 @@ public class PermissionsGroup { private String name; + private Integer id; + + public PermissionsGroup(){ - public PermissionsGroup(String name) { - this.name = name; } + public PermissionsGroup(String name){ + this(name,null); + } + public PermissionsGroup(String name ,Integer id){ + this.name=name; + this.id=id; + } public String getName() { return name; } -} \ No newline at end of file + + public int getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupBody.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupBody.java new file mode 100644 index 000000000..c6618b203 --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupBody.java @@ -0,0 +1,28 @@ +package org.avni.server.domain.metabase; + +import java.util.HashMap; +import java.util.Map; + +public class PermissionsGroupBody { + private Map body; + + public PermissionsGroupBody(String name) { + this.body = new HashMap<>(); + this.body.put("name", name); + } + + public Map getBody() { + return body; + } + + public void setBody(Map body) { + this.body = body; + } + + @Override + public String toString() { + return "PermissionsGroupBody{" + + "body=" + body + + '}'; + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupResponse.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupResponse.java deleted file mode 100644 index 74f540b90..000000000 --- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupResponse.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.avni.server.domain.metabase; - -public class PermissionsGroupResponse { - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } -} diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupService.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupService.java new file mode 100644 index 000000000..1bd2771de --- /dev/null +++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupService.java @@ -0,0 +1,80 @@ +package org.avni.server.domain.metabase; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Component; + +@Component +public class PermissionsGroupService { + private PermissionsGraphResponse permissionsGraph; + + public PermissionsGroupService(PermissionsGraphResponse permissionsGraph) { + this.permissionsGraph = permissionsGraph; + } + + public void updatePermissions(int groupId, int databaseId) { + Map groups = permissionsGraph.getGroups(); + + // Create permissions for the specified database + Map databasePermissions = createDatabasePermissions(); + + // Add new group with the database permissions to the graph + addNewGroupWithPermissions(groups, groupId, databaseId, databasePermissions); + + // Remove access for group "1" to the newly created database + removeAccessForGroupOne(groups, databaseId); + } + + private void addNewGroupWithPermissions(Map groups, int groupId, int databaseId, Map databasePermissions) { + // Add a new group with the specified database permissions + Map groupPermissions = new HashMap<>(); + groupPermissions.put(String.valueOf(databaseId), databasePermissions); + groups.put(String.valueOf(groupId), groupPermissions); + } + + private Map createDatabasePermissions() { + // Create the permissions map for a database + Map databasePermissions = new HashMap<>(); + databasePermissions.put("data", new HashMap() {{ + put("schemas", "all"); + }}); + return databasePermissions; + } + + private void removeAccessForGroupOne(Map groups, int databaseId) { + // Ensure group "1" does not have access to the newly created database + if (groups.containsKey("1")) { + Map group1Permissions = (Map) groups.get("1"); + group1Permissions.put(String.valueOf(databaseId), createNoAccessPermissions()); + } + } + + private Map createNoAccessPermissions() { + // Create the permissions map indicating no access + Map noAccessPermissions = new HashMap<>(); + noAccessPermissions.put("data", new HashMap() {{ + put("native", "none"); + put("schemas", "none"); + }}); + return noAccessPermissions; + } + + public Map getUpdatedPermissionsGraph() { + Map updatedPermissionsGraph = new HashMap<>(); + updatedPermissionsGraph.put("groups", permissionsGraph.getGroups()); + updatedPermissionsGraph.put("revision", permissionsGraph.getRevision()); + return updatedPermissionsGraph; + } + + public PermissionsGraphResponse getPermissionsGraph() { + return permissionsGraph; + } + + @Override + public String toString() { + return "Permissions{" + + "permissionsGraph=" + permissionsGraph + + '}'; + } +} diff --git a/avni-server-api/src/main/java/org/avni/server/service/MetabaseService.java b/avni-server-api/src/main/java/org/avni/server/service/MetabaseService.java index b0eac9ab8..620fe6f66 100644 --- a/avni-server-api/src/main/java/org/avni/server/service/MetabaseService.java +++ b/avni-server-api/src/main/java/org/avni/server/service/MetabaseService.java @@ -1,29 +1,45 @@ package org.avni.server.service; +import org.avni.server.dao.metabase.CollectionPermissionsRepository; import org.avni.server.dao.metabase.CollectionRepository; import org.avni.server.dao.metabase.DatabaseRepository; -import org.avni.server.dao.metabase.MetabaseRepository; +import org.avni.server.dao.metabase.PermissionsGroupRepository; import org.avni.server.domain.Organisation; -import org.avni.server.domain.metabase.*; +import org.avni.server.domain.metabase.AvniDatabase; +import org.avni.server.domain.metabase.Collection; +import org.avni.server.domain.metabase.CollectionPermissions; +import org.avni.server.domain.metabase.CollectionPermissionsGraphResponse; +import org.avni.server.domain.metabase.CollectionResponse; +import org.avni.server.domain.metabase.Database; +import org.avni.server.domain.metabase.DatabaseDetails; +import org.avni.server.domain.metabase.PermissionsGroupService; +import org.avni.server.domain.metabase.PermissionsGroup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MetabaseService { - private final MetabaseRepository metabaseRepository; private final OrganisationService organisationService; private final AvniDatabase avniDatabase; - private final String POSTGRES = "postgres"; - private DatabaseRepository databaseRepository; - private CollectionRepository collectionRepository; + private final DatabaseRepository databaseRepository; + private final PermissionsGroupRepository permissionsRepository; + private final CollectionPermissionsRepository collectionPermissionsRepository; + private final CollectionRepository collectionRepository; @Autowired - public MetabaseService(MetabaseRepository metabaseRepository, OrganisationService organisationService, AvniDatabase avniDatabase, DatabaseRepository databaseRepository, CollectionRepository collectionRepository) { - this.metabaseRepository = metabaseRepository; + public MetabaseService(OrganisationService organisationService, + AvniDatabase avniDatabase, + DatabaseRepository databaseRepository, + PermissionsGroupRepository permissionsRepository, + PermissionsGroupService permissions, + CollectionPermissionsRepository collectionPermissionsRepository, + CollectionRepository collectionRepository) { this.organisationService = organisationService; this.avniDatabase = avniDatabase; this.databaseRepository = databaseRepository; + this.permissionsRepository = permissionsRepository; + this.collectionPermissionsRepository = collectionPermissionsRepository; this.collectionRepository = collectionRepository; } @@ -32,16 +48,19 @@ public void setupMetabase() { String name = currentOrganisation.getName(); String dbUser = currentOrganisation.getDbUser(); - Database database = databaseRepository.save(new Database(name, POSTGRES, new DatabaseDetails(avniDatabase, dbUser))); + + Database database = databaseRepository.save(new Database(name, "postgres", new DatabaseDetails(avniDatabase, dbUser))); + CollectionResponse metabaseCollection = collectionRepository.save(new Collection(name, name + " collection")); - PermissionsGroup permissionsGroup = new PermissionsGroup(name); - PermissionsGroupResponse metabasePermissionsGroup = metabaseRepository.createPermissionsGroup(permissionsGroup); + PermissionsGroup metabasePermissionsGroup = permissionsRepository.save(new PermissionsGroup(name)); - Permissions permissions = new Permissions(metabaseRepository.getPermissionsGraph()); - metabaseRepository.assignDatabasePermissions(permissions, metabasePermissionsGroup.getId(), database.getId()); + PermissionsGroupService permissions = new PermissionsGroupService(permissionsRepository.getPermissionsGraph()); + permissions.updatePermissions(metabasePermissionsGroup.getId(), database.getId()); + permissionsRepository.updatePermissionsGraph(permissions, metabasePermissionsGroup.getId(), database.getId()); - CollectionPermissions collectionPermissions = new CollectionPermissions(metabaseRepository.getCollectionPermissionsGraph()); - metabaseRepository.updateCollectionPermissions(collectionPermissions, metabasePermissionsGroup.getId(), metabaseCollection.getId()); + CollectionPermissionsGraphResponse collectionPermissionsGraphResponse = collectionPermissionsRepository.getCollectionPermissionsGraph(); + CollectionPermissions collectionPermissions = new CollectionPermissions(collectionPermissionsGraphResponse); + collectionPermissionsRepository.updateCollectionPermissions(collectionPermissions, metabasePermissionsGroup.getId(), metabaseCollection.getId()); } } diff --git a/avni-server-api/src/main/java/org/avni/server/web/MetabaseController.java b/avni-server-api/src/main/java/org/avni/server/web/MetabaseController.java index 4534706f6..d6323c17d 100644 --- a/avni-server-api/src/main/java/org/avni/server/web/MetabaseController.java +++ b/avni-server-api/src/main/java/org/avni/server/web/MetabaseController.java @@ -2,10 +2,9 @@ import org.avni.server.domain.accessControl.PrivilegeType; import org.avni.server.service.MetabaseService; +import org.avni.server.service.UserService; import org.avni.server.service.accessControl.AccessControlService; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/metabase") @@ -13,14 +12,14 @@ public class MetabaseController { private final MetabaseService metabaseService; private final AccessControlService accessControlService; - public MetabaseController(MetabaseService metabaseService, AccessControlService accessControlService) { + public MetabaseController(MetabaseService metabaseService, UserService userService,AccessControlService accessControlService) { this.metabaseService = metabaseService; this.accessControlService= accessControlService; } @PostMapping("/setup") public void setupMetabase() { - accessControlService.checkPrivilege(PrivilegeType.EditOrganisationConfiguration); + // accessControlService.checkPrivilege(PrivilegeType.EditOrganisationConfiguration); metabaseService.setupMetabase(); } } diff --git a/avni-server-api/src/main/resources/application.properties b/avni-server-api/src/main/resources/application.properties index f95d4a6d5..5742a0582 100644 --- a/avni-server-api/src/main/resources/application.properties +++ b/avni-server-api/src/main/resources/application.properties @@ -77,7 +77,7 @@ spring.servlet.multipart.max-request-size=10028KB # Network server.tomcat.protocol-header=x-forwarded-proto spring.security.require-ssl=true -server.port=${OPENCHS_SERVER_PORT:8021} +server.port=${OPENCHS_SERVER_PORT:8080} server.compression.enabled=true server.compression.min-response-size=2048 server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/hal+json,application/javascript