From b48b8528980fae2a659d4c3b33af357472f31f98 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

---
 .../CollectionPermissionsRepository.java      | 28 +++++++
 .../dao/metabase/CollectionRepository.java    | 10 +--
 .../dao/metabase/DatabaseRepository.java      | 10 +--
 .../metabase/GroupPermissionsRepository.java  | 39 +++++++++
 ...Repository.java => MetabaseConnector.java} | 28 +++++--
 .../dao/metabase/MetabaseRepository.java      | 53 ------------
 .../dao/metabase/PermissionsRepository.java   |  4 -
 .../metabase/CollectionPermissions.java       | 29 -------
 .../CollectionPermissionsGraphResponse.java   | 27 +++++++
 .../CollectionPermissionsService.java         | 58 ++++++++++++++
 .../domain/metabase/CollectionResponse.java   |  3 +
 .../avni/server/domain/metabase/Database.java | 34 +++++++-
 .../domain/metabase/DatabaseDetails.java      |  8 +-
 .../avni/server/domain/metabase/Group.java    | 28 ++++---
 .../domain/metabase/GroupPermissionsBody.java | 28 +++++++
 .../GroupPermissionsGraphResponse.java        | 42 ++++++++++
 .../metabase/GroupPermissionsService.java     | 80 +++++++++++++++++++
 .../avni/server/domain/metabase/Groups.java   | 20 -----
 .../server/domain/metabase/Permissions.java   | 41 ----------
 .../domain/metabase/PermissionsGroup.java     | 13 ---
 .../metabase/PermissionsGroupResponse.java    | 13 ---
 .../avni/server/service/MetabaseService.java  | 47 +++++++----
 .../avni/server/web/MetabaseController.java   |  9 +--
 .../src/main/resources/application.properties |  4 +-
 24 files changed, 428 insertions(+), 228 deletions(-)
 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/GroupPermissionsRepository.java
 rename avni-server-api/src/main/java/org/avni/server/dao/metabase/{BaseMetabaseRepository.java => MetabaseConnector.java} (51%)
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseRepository.java
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/dao/metabase/PermissionsRepository.java
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissions.java
 create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsGraphResponse.java
 create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsService.java
 create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsBody.java
 create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsGraphResponse.java
 create mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsService.java
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/Groups.java
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/Permissions.java
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java
 delete mode 100644 avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroupResponse.java

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..40ed97f17
--- /dev/null
+++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/CollectionPermissionsRepository.java
@@ -0,0 +1,28 @@
+package org.avni.server.dao.metabase;
+
+import org.avni.server.domain.metabase.CollectionPermissionsService;
+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(CollectionPermissionsService collectionPermissionsService, int groupId, int collectionId) {
+        collectionPermissionsService.updatePermissions(groupId, collectionId);
+        String url = metabaseApiUrl + "/collection/graph";
+        sendPutRequest(url, collectionPermissionsService.getUpdatedPermissionsGraph());
+    }
+}
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<Collection> 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<Database> 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/GroupPermissionsRepository.java b/avni-server-api/src/main/java/org/avni/server/dao/metabase/GroupPermissionsRepository.java
new file mode 100644
index 000000000..15b1757d4
--- /dev/null
+++ b/avni-server-api/src/main/java/org/avni/server/dao/metabase/GroupPermissionsRepository.java
@@ -0,0 +1,39 @@
+package org.avni.server.dao.metabase;
+
+import org.avni.server.domain.metabase.GroupPermissionsService;
+import org.avni.server.domain.metabase.GroupPermissionsGraphResponse;
+import org.avni.server.domain.metabase.Group;
+import org.avni.server.domain.metabase.GroupPermissionsBody;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.HttpEntity;
+import org.springframework.stereotype.Repository;
+
+import java.util.Map;
+
+@Repository
+public class GroupPermissionsRepository extends MetabaseConnector {
+
+    public GroupPermissionsRepository(RestTemplateBuilder restTemplateBuilder) {
+        super(restTemplateBuilder);
+    }
+
+        public Group save(Group permissionsGroup) {
+        String url = metabaseApiUrl + "/permissions/group";
+        GroupPermissionsBody body = new GroupPermissionsBody(permissionsGroup.getName());
+        HttpEntity<Map<String, Object>> entity = createJsonEntity(body);
+
+        Group response = restTemplate.postForObject(url, entity, Group.class);
+        return response;
+    }
+
+    public GroupPermissionsGraphResponse getPermissionsGraph() {
+        String url = metabaseApiUrl + "/permissions/graph";
+        return getForObject(url, GroupPermissionsGraphResponse.class);
+    }
+
+    public void updatePermissionsGraph(GroupPermissionsService permissions, int groupId, int databaseId) {
+        String url = metabaseApiUrl + "/permissions/graph";
+        Map<String, Object> requestBody = permissions.getUpdatedPermissionsGraph();
+        sendPutRequest(url, requestBody);
+    }
+}
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/MetabaseConnector.java
similarity index 51%
rename from avni-server-api/src/main/java/org/avni/server/dao/metabase/BaseMetabaseRepository.java
rename to avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseConnector.java
index 780989568..d7f227e24 100644
--- 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/MetabaseConnector.java
@@ -1,5 +1,6 @@
 package org.avni.server.dao.metabase;
 
+import org.avni.server.domain.metabase.GroupPermissionsBody;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.web.client.RestTemplateBuilder;
 import org.springframework.http.HttpEntity;
@@ -8,11 +9,10 @@
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Repository;
 import org.springframework.web.client.RestTemplate;
-
 import java.util.Map;
 
 @Repository
-public class BaseMetabaseRepository {
+public class MetabaseConnector {
     protected final RestTemplate restTemplate;
 
     @Value("${metabase.api.url}")
@@ -21,11 +21,11 @@ public class BaseMetabaseRepository {
     @Value("${metabase.api.key}")
     private String apiKey;
 
-    public BaseMetabaseRepository(RestTemplateBuilder restTemplateBuilder) {
+    public MetabaseConnector(RestTemplateBuilder restTemplateBuilder) {
         this.restTemplate = restTemplateBuilder.build();
     }
 
-    private HttpHeaders getHeaders() {
+    protected HttpHeaders getHeaders() {
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(MediaType.APPLICATION_JSON);
         headers.set("x-api-key", apiKey);
@@ -37,8 +37,24 @@ protected <T> HttpEntity<T> createHttpEntity(T body) {
         return new HttpEntity<>(body, headers);
     }
 
-    protected void sendPutRequest(String url, Map<String, Object> requestBody) {
-        HttpEntity<Map<String, Object>> entity = createHttpEntity(requestBody);
+    protected void sendPutRequest(String url, Map<String, ?> requestBody) {
+        HttpEntity<Map<String, ?>> entity = createHttpEntity(requestBody);
         restTemplate.exchange(url, HttpMethod.PUT, entity, Map.class);
     }
+
+    protected <T> T postForObject(String url, Object request, Class<T> responseType) {
+        HttpEntity<Object> entity = createHttpEntity(request);
+        return restTemplate.postForObject(url, entity, responseType);
+    }
+
+    protected <T> T getForObject(String url, Class<T> responseType) {
+        HttpHeaders headers = getHeaders();
+        HttpEntity<Void> entity = new HttpEntity<>(headers);
+        return restTemplate.exchange(url, HttpMethod.GET, entity, responseType).getBody();
+    }
+
+    protected HttpEntity<Map<String, Object>> createJsonEntity(GroupPermissionsBody 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<PermissionsGroup> entity = createHttpEntity(permissionsGroup);
-        PermissionsGroupResponse response = restTemplate.postForObject(url, entity, PermissionsGroupResponse.class);
-
-        return response;
-    }
-
-    public Map<String, Object> getPermissionsGraph() {
-        String url = metabaseApiUrl + "/permissions/graph";
-        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, createHttpEntity(null), Map.class);
-        return response.getBody();
-    }
-
-    public Map<String, Object> getCollectionPermissionsGraph() {
-        String url = metabaseApiUrl + "/collection/graph";
-        ResponseEntity<Map> 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/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
deleted file mode 100644
index 963af0e23..000000000
--- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissions.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.avni.server.domain.metabase;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class CollectionPermissions {
-    private Map<String, Object> permissionsGraph;
-
-    public CollectionPermissions(Map<String, Object> permissionsGraph) {
-        this.permissionsGraph = permissionsGraph;
-    }
-
-    public Map<String, Object> getPermissionsGraph() {
-        return permissionsGraph;
-    }
-
-    public void updatePermissionsGraph(int groupId, int collectionId) {
-        Map<String, Map<String, String>> groups = (Map<String, Map<String, String>>) permissionsGraph.get("groups");
-
-        groups.computeIfAbsent(String.valueOf(groupId), k -> new HashMap<>());
-        Map<String, String> groupPermissions = groups.get(String.valueOf(groupId));
-        groupPermissions.put(String.valueOf(collectionId), "write");
-
-        if (groups.containsKey("1")) {
-            Map<String, String> allGroupPermissions = groups.get("1");
-            allGroupPermissions.put(String.valueOf(collectionId), "none");
-        }
-    }
-}
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<String, Map<String, String>> groups;
+
+    public int getRevision() {
+        return revision;
+    }
+
+    public void setRevision(int revision) {
+        this.revision = revision;
+    }
+
+    public Map<String, Map<String, String>> getGroups() {
+        return groups;
+    }
+
+    public void setGroups(Map<String, Map<String, String>> groups) {
+        this.groups = groups;
+    }
+}
diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsService.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsService.java
new file mode 100644
index 000000000..941f7bfa7
--- /dev/null
+++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionPermissionsService.java
@@ -0,0 +1,58 @@
+package org.avni.server.domain.metabase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class CollectionPermissionsService {
+    private final CollectionPermissionsGraphResponse permissionsGraph;
+
+    public CollectionPermissionsService(CollectionPermissionsGraphResponse permissionsGraph) {
+        this.permissionsGraph = permissionsGraph;
+    }
+
+    public void updatePermissions(int groupId, int collectionId) {
+        Map<String, Map<String, String>> groups = permissionsGraph.getGroups();
+
+        ensureGroupsMapExists(groups);
+
+        Map<String, String> groupPermissions = getOrCreateGroupPermissions(groups, groupId);
+        updateGroupPermissions(groupPermissions, collectionId);
+
+        handleSpecialGroupPermissions(groups, collectionId);
+    }
+
+    private void ensureGroupsMapExists(Map<String, Map<String, String>> groupsMap) {
+        if (groupsMap == null) {
+            throw new RuntimeException("Groups not found in the collection permissions graph.");
+        }
+    }
+
+    private Map<String, String> getOrCreateGroupPermissions(Map<String, Map<String, String>> groupsMap, int groupId) {
+        return groupsMap.computeIfAbsent(String.valueOf(groupId), k -> new HashMap<>());
+    }
+
+    private void updateGroupPermissions(Map<String, String> groupPermissions, int collectionId) {
+        groupPermissions.put(String.valueOf(collectionId), "write");
+    }
+
+    private void handleSpecialGroupPermissions(Map<String, Map<String, String>> groupsMap, int collectionId) {
+        if (groupsMap.containsKey("1")) {
+            Map<String, String> group1Permissions = groupsMap.get("1");
+            group1Permissions.put(String.valueOf(collectionId), "none");
+        }
+    }
+
+    public Map<String, Object> getUpdatedPermissionsGraph() {
+        Map<String, Object> updatedPermissionsGraph = new HashMap<>();
+        updatedPermissionsGraph.put("groups", permissionsGraph.getGroups());
+        updatedPermissionsGraph.put("revision", permissionsGraph.getRevision());
+        return updatedPermissionsGraph;
+    }
+
+    public CollectionPermissionsGraphResponse getPermissionsGraph() {
+        return permissionsGraph;
+    }
+}
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/Group.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/Group.java
index f1874c183..01941662b 100644
--- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Group.java
+++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/Group.java
@@ -1,23 +1,33 @@
 package org.avni.server.domain.metabase;
 
 public class Group {
-    private int id;
-    private boolean hasPermission;
+    private String name;
+    private Integer id;
+
+    public Group(){
 
-    public Group(int id, boolean hasPermission) {
-        this.id = id;
-        this.hasPermission = hasPermission;
+    }
+    public Group(String name){
+        this(name,null);
+
+    }
+    public Group(String name ,Integer id){
+        this.name=name;
+        this.id=id;
+    }
+    public String getName() {
+        return name;
     }
 
     public int getId() {
         return id;
     }
 
-    public boolean hasPermission() {
-        return hasPermission;
+    public void setName(String name) {
+        this.name = name;
     }
 
-    public void setPermission(boolean hasPermission) {
-        this.hasPermission = hasPermission;
+    public void setId(int id) {
+        this.id = id;
     }
 }
diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsBody.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsBody.java
new file mode 100644
index 000000000..50632e6ba
--- /dev/null
+++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsBody.java
@@ -0,0 +1,28 @@
+package org.avni.server.domain.metabase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class GroupPermissionsBody {
+    private Map<String, Object> body;
+
+    public GroupPermissionsBody(String name) {
+        this.body = new HashMap<>();
+        this.body.put("name", name);
+    }
+
+    public Map<String, Object> getBody() {
+        return body;
+    }
+
+    public void setBody(Map<String, Object> 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/GroupPermissionsGraphResponse.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsGraphResponse.java
new file mode 100644
index 000000000..d56812b5c
--- /dev/null
+++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsGraphResponse.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 GroupPermissionsGraphResponse {
+    @JsonProperty("groups")
+    private Map<String, Object> groups;
+
+    @JsonProperty("revision")
+    private int revision;
+
+    public Map<String, Object> getGroups() {
+        return groups;
+    }
+
+    public void setGroups(Map<String, Object> 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/GroupPermissionsService.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsService.java
new file mode 100644
index 000000000..06e8c79d3
--- /dev/null
+++ b/avni-server-api/src/main/java/org/avni/server/domain/metabase/GroupPermissionsService.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 GroupPermissionsService {
+    private GroupPermissionsGraphResponse permissionsGraph;
+
+    public GroupPermissionsService(GroupPermissionsGraphResponse permissionsGraph) {
+        this.permissionsGraph = permissionsGraph;
+    }
+
+    public void updatePermissions(int groupId, int databaseId) {
+        Map<String, Object> groups = permissionsGraph.getGroups();
+
+        // Create permissions for the specified database
+        Map<String, Object> 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
+        removeAccessForAllOtherGroups(groups, databaseId);
+    }
+
+    private void addNewGroupWithPermissions(Map<String, Object> groups, int groupId, int databaseId, Map<String, Object> databasePermissions) {
+        // Add a new group with the specified database permissions
+        Map<String, Object> groupPermissions = new HashMap<>();
+        groupPermissions.put(String.valueOf(databaseId), databasePermissions);
+        groups.put(String.valueOf(groupId), groupPermissions);
+    }
+
+    private Map<String, Object> createDatabasePermissions() {
+        // Create the permissions map for a database
+        Map<String, Object> databasePermissions = new HashMap<>();
+        databasePermissions.put("data", new HashMap<String, String>() {{
+            put("schemas", "all");
+        }});
+        return databasePermissions;
+    }
+
+    private void removeAccessForAllOtherGroups(Map<String, Object> groups, int databaseId) {
+        // Ensure group "1" does not have access to the newly created database
+        if (groups.containsKey("1")) {
+            Map<String, Object> group1Permissions = (Map<String, Object>) groups.get("1");
+            group1Permissions.put(String.valueOf(databaseId), createNoAccessPermissions());
+        }
+    }
+
+    private Map<String, Object> createNoAccessPermissions() {
+        // Create the permissions map indicating no access
+        Map<String, Object> noAccessPermissions = new HashMap<>();
+        noAccessPermissions.put("data", new HashMap<String, String>() {{
+            put("native", "none");
+            put("schemas", "none");
+        }});
+        return noAccessPermissions;
+    }
+
+    public Map<String, Object> getUpdatedPermissionsGraph() {
+        Map<String, Object> updatedPermissionsGraph = new HashMap<>();
+        updatedPermissionsGraph.put("groups", permissionsGraph.getGroups());
+        updatedPermissionsGraph.put("revision", permissionsGraph.getRevision());
+        return updatedPermissionsGraph;
+    }
+
+    public GroupPermissionsGraphResponse getPermissionsGraph() {
+        return permissionsGraph;
+    }
+
+    @Override
+    public String toString() {
+        return "Permissions{" +
+                "permissionsGraph=" + permissionsGraph +
+                '}';
+    }
+}
diff --git a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Groups.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/Groups.java
deleted file mode 100644
index d355e5f27..000000000
--- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/Groups.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.avni.server.domain.metabase;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Groups {
-    private List<Group> groups = new ArrayList<>();
-
-    public void addGroup(Group group) {
-        groups.add(group);
-    }
-
-    public Group getGroupById(int id) {
-        return groups.stream().filter(g -> g.getId() == id).findFirst().orElse(null);
-    }
-
-    public List<Group> getGroups() {
-        return groups;
-    }
-}
\ No newline at end of file
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<String, Object> permissionsGraph;
-
-    public Permissions(Map<String, Object> permissionsGraph) {
-        this.permissionsGraph = permissionsGraph;
-    }
-
-    public Map<String, Object> getPermissionsGraph() {
-        return permissionsGraph;
-    }
-
-    public void updatePermissionsGraph(int groupId, int databaseId) {
-        Map<String, Object> groups = (Map<String, Object>) permissionsGraph.get("groups");
-
-        Map<String, Object> databasePermissions = new HashMap<>();
-        databasePermissions.put("data", new HashMap<String, String>() {{
-            put("schemas", "all");
-        }});
-
-        groups.computeIfAbsent(String.valueOf(groupId), k -> new HashMap<>());
-        Map<String, Object> groupPermissions = (Map<String, Object>) groups.get(String.valueOf(groupId));
-        groupPermissions.put(String.valueOf(databaseId), databasePermissions);
-
-        if (groups.containsKey("1")) {
-            Map<String, Object> allGroupsPermissionsMap = (Map<String, Object>) groups.get("1");
-            if (allGroupsPermissionsMap.containsKey(String.valueOf(databaseId))) {
-                Map<String, Object> allGroupsDatabasePermissions = (Map<String, Object>) allGroupsPermissionsMap.get(String.valueOf(databaseId));
-                if (allGroupsDatabasePermissions.containsKey("data")) {
-                    Map<String, String> dataPermissions = (Map<String, String>) 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/PermissionsGroup.java b/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java
deleted file mode 100644
index b4b1e9003..000000000
--- a/avni-server-api/src/main/java/org/avni/server/domain/metabase/PermissionsGroup.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.avni.server.domain.metabase;
-
-public class PermissionsGroup {
-    private String name;
-
-    public PermissionsGroup(String name) {
-        this.name = name;
-    }
-
-    public String getName() {
-        return name;
-    }
-}
\ No newline at end of file
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/service/MetabaseService.java b/avni-server-api/src/main/java/org/avni/server/service/MetabaseService.java
index b0eac9ab8..b67316a55 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,44 @@
 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.GroupPermissionsRepository;
 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.CollectionPermissionsService;
+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.Group;
+import org.avni.server.domain.metabase.GroupPermissionsService;
 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 GroupPermissionsRepository groupPermissionsRepository;
+    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,
+                           GroupPermissionsRepository groupPermissionsRepository,
+                           GroupPermissionsService permissions,
+                           CollectionPermissionsRepository collectionPermissionsRepository,
+                           CollectionRepository collectionRepository) {
         this.organisationService = organisationService;
         this.avniDatabase = avniDatabase;
         this.databaseRepository = databaseRepository;
+        this.groupPermissionsRepository = groupPermissionsRepository;
+        this.collectionPermissionsRepository = collectionPermissionsRepository;
         this.collectionRepository = collectionRepository;
     }
 
@@ -32,16 +47,18 @@ 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);
+        Group metabaseGroup = groupPermissionsRepository.save(new Group(name));
 
-        Permissions permissions = new Permissions(metabaseRepository.getPermissionsGraph());
-        metabaseRepository.assignDatabasePermissions(permissions, metabasePermissionsGroup.getId(), database.getId());
+        GroupPermissionsService groupPermissions = new GroupPermissionsService(groupPermissionsRepository.getPermissionsGraph());
+        groupPermissions.updatePermissions(metabaseGroup.getId(), database.getId());
+        groupPermissionsRepository.updatePermissionsGraph(groupPermissions, metabaseGroup.getId(), database.getId());
 
-        CollectionPermissions collectionPermissions = new CollectionPermissions(metabaseRepository.getCollectionPermissionsGraph());
-        metabaseRepository.updateCollectionPermissions(collectionPermissions, metabasePermissionsGroup.getId(), metabaseCollection.getId());
+        CollectionPermissionsService collectionPermissions = new CollectionPermissionsService(collectionPermissionsRepository.getCollectionPermissionsGraph());
+        collectionPermissions.updatePermissions(metabaseGroup.getId(), metabaseCollection.getId());
+        collectionPermissionsRepository.updateCollectionPermissions(collectionPermissions, metabaseGroup.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..e30c9fb9c 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
@@ -160,4 +160,4 @@ avni.reportingSystems[2].url=${AVNI_REPORTING_SYSTEM_2_URL:}
 
 #metabase
 metabase.api.url=${METABASE_API_URL:http://localhost:3000/api}
-metabase.api.key=${METABASE_API_KEY:mb_hwsYP2sFN7fvwM5LTS4d/tnIqA5SeHUxwUhm2KAI1/o=}
+metabase.api.key=${METABASE_API_KEY:mb_RXwY6ip5FKeVjrP3EdZOQrDyajrKBTT7FXF6X2anUCg=}