This is an automated email from the ASF dual-hosted git repository. machristie pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/airavata-data-catalog.git
commit 2e6393961620230cfbdc9ad5f4f799904905a728 Author: Marcus Christie <[email protected]> AuthorDate: Thu Jan 26 11:19:20 2023 -0500 Initial work on sharing management interface --- .../datacatalog/api/model/DataProductEntity.java | 11 ++- .../airavata/datacatalog/api/model/UserEntity.java | 79 ++++++++++++++++ .../api/service/DataCatalogAPIService.java | 4 + .../datacatalog/api/sharing/SharingManager.java | 102 +++++++++++++++++++++ .../stubs/src/main/proto/DataCatalogAPI.proto | 18 ++++ 5 files changed, 209 insertions(+), 5 deletions(-) diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java index c9a67d2..65b24e7 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/DataProductEntity.java @@ -22,27 +22,28 @@ import jakarta.persistence.UniqueConstraint; public class DataProductEntity { @Id - @SequenceGenerator(name="data_product_data_product_id_seq", sequenceName = "data_product_data_product_id_seq", allocationSize = 1) + @SequenceGenerator(name = "data_product_data_product_id_seq", sequenceName = "data_product_data_product_id_seq", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "data_product_data_product_id_seq") - @Column(name="data_product_id") + @Column(name = "data_product_id") private Long dataProductId; @ManyToOne(optional = true) - @JoinColumn(name="parent_data_product_id", referencedColumnName = "data_product_id", nullable = true) + @JoinColumn(name = "parent_data_product_id", referencedColumnName = "data_product_id", nullable = true) private DataProductEntity parentDataProductEntity; @Basic - @Column(name="external_id", nullable = false) + @Column(name = "external_id", nullable = false) private String externalId; @Basic - @Column(name="name", nullable = false) + @Column(name = "name", nullable = false) private String name; @Type(JsonType.class) @Column(name = "metadata", columnDefinition = "jsonb") private JsonNode metadata; + // TODO: ManyToOne mapping to owner: UserEntity public Long getDataProductId() { return dataProductId; } diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java new file mode 100644 index 0000000..0540ab2 --- /dev/null +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/model/UserEntity.java @@ -0,0 +1,79 @@ +package org.apache.airavata.datacatalog.api.model; + +import jakarta.persistence.Basic; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.SequenceGenerator; +import jakarta.persistence.Table; + +@Entity +@Table(name = "user") +public class UserEntity { + + @Id + @SequenceGenerator(name = "user_user_id_seq", sequenceName = "user_user_id_seq", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_user_id_seq") + @Column(name = "user_id") + private Long userId; + + @Basic + @Column(name = "external_id", nullable = false) + private String externalId; + + @Basic + @Column(name = "name", nullable = false) + private String name; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((userId == null) ? 0 : userId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + UserEntity other = (UserEntity) obj; + if (userId == null) { + if (other.userId != null) + return false; + } else if (!userId.equals(other.userId)) + return false; + return true; + } + +} diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java index fa979a6..e14c437 100644 --- a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/service/DataCatalogAPIService.java @@ -30,6 +30,7 @@ public class DataCatalogAPIService extends DataCatalogAPIServiceGrpc.DataCatalog public void createDataProduct(DataProductCreateRequest request, StreamObserver<DataProductCreateResponse> responseObserver) { + // TODO: SharingManager.resolveUser logger.info("Creating data product {}", request.getDataProduct()); DataProductEntity dataProductEntity = new DataProductEntity(); dataProductEntity.setExternalId(UUID.randomUUID().toString()); @@ -51,6 +52,9 @@ public class DataCatalogAPIService extends DataCatalogAPIServiceGrpc.DataCatalog } DataProductEntity savedDataProductEntity = dataProductRepository.save(dataProductEntity); + // TODO: SharingManager.grantPermissionToUser(userInfo, dataProduct, + // Permission.OWNER) + DataProductCreateResponse.Builder responseBuilder = DataProductCreateResponse.newBuilder(); responseBuilder.getDataProductBuilder() .setDataProductId(savedDataProductEntity.getExternalId()) diff --git a/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManager.java b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManager.java new file mode 100644 index 0000000..cbe470e --- /dev/null +++ b/data-catalog-api/server/src/main/java/org/apache/airavata/datacatalog/api/sharing/SharingManager.java @@ -0,0 +1,102 @@ +package org.apache.airavata.datacatalog.api.sharing; + +import org.apache.airavata.datacatalog.api.DataProduct; +import org.apache.airavata.datacatalog.api.GroupInfo; +import org.apache.airavata.datacatalog.api.Permission; +import org.apache.airavata.datacatalog.api.UserInfo; +import org.apache.airavata.datacatalog.api.model.UserEntity; + +public interface SharingManager { + + /** + * Get or create a {@link UserEntity}. + * + * @param userInfo + * @return + */ + UserEntity resolveUser(UserInfo userInfo); + + /** + * Return true if the user has access to the data product with the given + * permission. + * + * @param userInfo + * @param dataProduct + * @param permission + * @return + */ + boolean userHasAccess(UserInfo userInfo, DataProduct dataProduct, Permission permission); + + /** + * Return the name of the database view that includes sharing information + * for each data product. The view should contain the following columns: + * data_product_id, user_id, and permission_id where the permission_id + * should be a number as defined in the {@link Permission} enum. + * + * @return + */ + String getDataProductSharingView(); + + /** + * Grant permission to the user for the given data product. + * + * @param userInfo + * @param dataProduct + * @param permission + */ + void grantPermissionToUser(UserInfo userInfo, DataProduct dataProduct, Permission permission); + + /** + * Revoke permission from the user for the given data product. + * + * @param userInfo + * @param dataProduct + * @param permission + */ + void revokePermissionFromUser(UserInfo userInfo, DataProduct dataProduct, Permission permission); + + /** + * Grant permission to the group for the given data product. + * + * @param groupInfo + * @param dataProduct + * @param permission + */ + void grantPermissionToGroup(GroupInfo groupInfo, DataProduct dataProduct, Permission permission); + + /** + * Revoke permission from the group for the given data product. + * + * @param groupInfo + * @param dataProduct + * @param permission + */ + void revokePermissionFromGroup(GroupInfo groupInfo, DataProduct dataProduct, Permission permission); + + /** + * Return true if public access at the given permission is granted for the + * given data product. Public access means anonymous access; no user information + * provided in the API request. + * + * @param dataProduct + * @param permission + * @return + */ + boolean hasPublicAccess(DataProduct dataProduct, Permission permission); + + /** + * Grant public access to the given data product. + * + * @param dataProduct + * @param permission + */ + void grantPublicAccess(DataProduct dataProduct, Permission permission); + + /** + * Revoke public access from the given data product. + * + * @param dataProduct + * @param permission + */ + void revokePublicAccess(DataProduct dataProduct, Permission permission); +} diff --git a/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto b/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto index 43854f9..bc8f656 100644 --- a/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto +++ b/data-catalog-api/stubs/src/main/proto/DataCatalogAPI.proto @@ -20,6 +20,24 @@ syntax = "proto3"; option java_multiple_files = true; option java_package = "org.apache.airavata.datacatalog.api"; +message UserInfo { + string user_id = 1; + optional string tenant_id = 2; +} + +message GroupInfo { + string group_id = 1; + optional string tenant_id = 2; +} + +enum Permission { + OWNER = 0; + READ = 1; + READ_METADATA = 2; + WRITE = 3; + WRITE_METADATA = 4; + MANAGE_SHARING = 5; +} message DataProduct { string data_product_id = 1;
