Skip to content

Commit

Permalink
Consider public data as readable from users of any organisation, and …
Browse files Browse the repository at this point in the history
…'anonymous' ones.
  • Loading branch information
MohamedHamouGisaia committed Jan 2, 2025
1 parent 9d12915 commit 0b0e8e1
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
*/
package io.arlas.persistence.server.core;

import io.arlas.commons.exceptions.ArlasException;
import io.arlas.filter.core.IdentityParam;
import io.arlas.persistence.server.exceptions.ForbiddenException;
import io.arlas.persistence.server.model.Data;
import io.arlas.persistence.server.utils.SortOrder;
import org.apache.commons.lang3.tuple.Pair;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.tuple.Pair;

import io.arlas.commons.exceptions.ArlasException;
import static io.arlas.filter.config.TechnicalRoles.GROUP_PUBLIC;
import io.arlas.filter.core.IdentityParam;
import io.arlas.persistence.server.exceptions.ForbiddenException;
import io.arlas.persistence.server.model.Data;
import io.arlas.persistence.server.utils.SortOrder;

public interface PersistenceService {

Expand Down Expand Up @@ -98,13 +98,46 @@ static boolean isPublic(Data data) {
return data.getDocReaders().contains(GROUP_PUBLIC) || data.getDocWriters().contains(GROUP_PUBLIC);
}

/**
* A user can read data if:
* - data is public
* - OR (
* User is authenticated
* AND
* User belongs to the doc's organisation in IAM mode
* AND
* (
* User is owner of the doc
* OR
* User belongs to the doc readers.
* )
* ).
*/
static boolean isReaderOnData(IdentityParam idp, Data data) {
return (idp.isAnonymous || idp.organisation.contains(data.getDocOrganization())) &&
(data.getDocOwner().equals(idp.userId) || intersect(idp.groups, data.getDocReaders()));
return isPublic(data) ||
(
!idp.isAnonymous &&
idp.organisation.contains(data.getDocOrganization()) && /** Always true in case of an KeyCloak Policy inforcer, as idp and doc organisations are both empty strings "". */
(data.getDocOwner().equals(idp.userId) || intersect(idp.groups, data.getDocReaders()))
);
}

/**
* A user can read data if:
* User is authenticated
* AND
* User belongs to the doc's organisation in IAM mode
* AND
* (
* User is owner of the doc
* OR
* User belongs to the doc writers.
* ).
*/
static boolean isWriterOnData(IdentityParam idp, Data data) {
return (idp.isAnonymous || idp.organisation.contains(data.getDocOrganization())) &&
(data.getDocOwner().equals(idp.userId) || intersect(idp.groups, data.getDocWriters()));
return !idp.isAnonymous &&
idp.organisation.contains(data.getDocOrganization()) && /** Always true in case of an KeyCloak Policy inforcer, as idp and doc organisations are both empty strings "". */
(data.getDocOwner().equals(idp.userId)
|| intersect(idp.groups, data.getDocWriters()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,25 @@

package io.arlas.persistence.rest;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.hamcrest.Matchers.equalTo;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import java.util.*;

import static io.restassured.RestAssured.delete;
import io.restassured.RestAssured;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
import io.restassured.http.ContentType;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PersistenceIT {
Expand Down Expand Up @@ -514,6 +519,33 @@ public void test22CreateWithPublicWriteAccess() {

}

@Test
public void test23PublicDataAccess() {
id = createData(technical, "myPublicData", List.of(PUBLIC), Collections.EMPTY_LIST)
.then().statusCode(201)
.body("doc_value", equalTo("{\"age\":1}"))
.extract().jsonPath().get("id");



getData(technical, id).then().statusCode(200);
getData(otherCompany, id).then().statusCode(200);
getDataAsAnonymous(id).then().statusCode(200);
}

@Test
public void test24OrganisationDataAccess() {
id = createData(technical, "myOrgaData", List.of(ALL), Collections.EMPTY_LIST)
.then().statusCode(201)
.body("doc_value", equalTo("{\"age\":1}"))
.extract().jsonPath().get("id");

getData(technical, id).then().statusCode(200);
getData(commercial, id).then().statusCode(200);
getData(otherCompany, id).then().statusCode(403);
getDataAsAnonymous(id).then().statusCode(403);
}

protected RequestSpecification givenForUser(UserIdentity userIdentity) {
return given().header(userHeader, userIdentity.userId)
.header(groupsHeader, userIdentity.groups)
Expand Down Expand Up @@ -548,6 +580,13 @@ protected Response getData(UserIdentity userIdentity, String id) {
.get(arlasAppPath.concat("resource/id/{id}"));
}

protected Response getDataAsAnonymous(String id) {
return given()
.pathParam("id", id)
.when()
.get(arlasAppPath.concat("resource/id/{id}"));
}


protected void listEmpty(UserIdentity userIdentity) {
givenForUser(userIdentity)
Expand Down

0 comments on commit 0b0e8e1

Please sign in to comment.