Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
bobeal committed Feb 28, 2023
2 parents 921973c + 95f2456 commit 205687a
Show file tree
Hide file tree
Showing 138 changed files with 3,788 additions and 2,918 deletions.
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
indent_size=4
insert_final_newline=true
max_line_length=120
disabled_rules=no-wildcard-imports,experimental:multiline-if-else
ktlint_standard_no-wildcard-imports=false
ktlint_standard_multiline-if-else=false
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ STELLIO_AUTHENTICATION_ENABLED=false
ENVIRONMENT=docker

APPLICATION_ENTITY_SERVICE_URL=http://search-service:8083

# Used as a base URL by subscription service when serving contexts for notifications
APPLICATION_STELLIO_URL=http://localhost:8080
2 changes: 1 addition & 1 deletion .github/workflows/cla.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: "CLA Assistant"
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
# Beta Release
uses: cla-assistant/github-action@v2.2.1
uses: cla-assistant/github-action@v2.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# the below token should have repo scope and must be manually added by you in the repository's secret
Expand Down
76 changes: 76 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ "develop" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "develop" ]
schedule:
- cron: '34 6 * * 3'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality


# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
3 changes: 3 additions & 0 deletions .sdkmanrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=17.0.6-tem
15 changes: 8 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@ plugins {
java
// only apply the plugin in the subprojects requiring it because it expects a Spring Boot app
// and the shared lib is obviously not one
id("org.springframework.boot") version "3.0.2" apply false
id("org.springframework.boot") version "3.0.3" apply false
id("io.spring.dependency-management") version "1.1.0" apply false
id("org.graalvm.buildtools.native") version "0.9.19"
id("org.graalvm.buildtools.native") version "0.9.20"
kotlin("jvm") version "1.8.10" apply false
kotlin("plugin.spring") version "1.8.10" apply false
id("org.jlleitschuh.gradle.ktlint") version "11.1.0"
id("org.jlleitschuh.gradle.ktlint") version "11.2.0"
id("com.google.cloud.tools.jib") version "3.3.1" apply false
id("io.gitlab.arturbosch.detekt") version "1.22.0" apply false
id("org.sonarqube") version "3.5.0.2730"
id("org.sonarqube") version "4.0.0.2929"
jacoco
}

subprojects {
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}

apply(plugin = "io.spring.dependency-management")
Expand Down Expand Up @@ -92,7 +93,7 @@ subprojects {
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict", "-opt-in=kotlin.RequiresOptIn")
jvmTarget = "17"
jvmTarget = "${JavaVersion.VERSION_17}"
}
}
tasks.withType<Test> {
Expand All @@ -104,7 +105,7 @@ subprojects {
}

ktlint {
disabledRules.set(setOf("experimental:multiline-if-else", "no-wildcard-imports"))
disabledRules.set(setOf("multiline-if-else", "no-wildcard-imports"))
reporters {
reporter(ReporterType.CHECKSTYLE)
reporter(ReporterType.PLAIN)
Expand Down Expand Up @@ -174,7 +175,7 @@ subprojects {

allprojects {
group = "com.egm.stellio"
version = "2.1.0"
version = "2.2.0"

repositories {
mavenCentral()
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ services:
- SPRING_R2DBC_PASSWORD=${POSTGRES_PASS}
- APPLICATION_AUTHENTICATION_ENABLED=${STELLIO_AUTHENTICATION_ENABLED}
- APPLICATION_ENTITY_SERVICE-URL=${APPLICATION_ENTITY_SERVICE_URL}
- APPLICATION_STELLIO_URL=${APPLICATION_STELLIO_URL}
ports:
- "8084:8084"
depends_on:
Expand Down
3 changes: 2 additions & 1 deletion search-service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ dependencies {
implementation("org.flywaydb:flyway-core")
// implementation (and not runtime) because we are using the native jsonb encoding provided by PG
implementation("org.postgresql:r2dbc-postgresql")
implementation("com.savvasdalkitsis:json-merge:0.0.6")
implementation("com.github.stellio-hub:json-merge:0.1.0")
implementation("org.json:json:20230227")
implementation(project(":shared"))

detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.22.0")
Expand Down
18 changes: 7 additions & 11 deletions search-service/config/detekt/baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,21 @@
<ID>Filename:db.migration.V0_29__JsonLd_migration.kt:1</ID>
<ID>LongMethod:AttributeInstanceService.kt$AttributeInstanceService$@Transactional suspend fun create(attributeInstance: AttributeInstance): Either&lt;APIException, Unit&gt;</ID>
<ID>LongMethod:EntityAccessControlHandler.kt$EntityAccessControlHandler$@PostMapping("/{subjectId}/attrs", consumes = [MediaType.APPLICATION_JSON_VALUE, JSON_LD_CONTENT_TYPE]) suspend fun addRightsOnEntities( @RequestHeader httpHeaders: HttpHeaders, @PathVariable subjectId: String, @RequestBody requestBody: Mono&lt;String&gt; ): ResponseEntity&lt;*&gt;</ID>
<ID>LongMethod:EntityEventServiceTests.kt$EntityEventServiceTests$@Test fun `it should publish ATTRIBUTE_APPEND and ATTRIBUTE_REPLACE events if attributes were appended and replaced`()</ID>
<ID>LongMethod:EntityEventServiceTests.kt$EntityEventServiceTests$@Test fun `it should publish ATTRIBUTE_REPLACE events if a multi-attribute is replaced`()</ID>
<ID>LongMethod:EntityEventServiceTests.kt$EntityEventServiceTests$@Test fun `it should publish ATTRIBUTE_REPLACE events if two attributes are replaced`()</ID>
<ID>LongMethod:ParameterizedTests.kt$ParameterizedTests.Companion$@JvmStatic fun rawResultsProvider(): Stream&lt;Arguments&gt;</ID>
<ID>LongMethod:QueryServiceTests.kt$QueryServiceTests$@Test fun `it should query temporal entities as requested by query params`()</ID>
<ID>LongMethod:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$@Transactional suspend fun appendEntityAttributes( entityUri: URI, ngsiLdAttributes: List&lt;NgsiLdAttribute&gt;, jsonLdAttributes: Map&lt;String, Any&gt;, disallowOverwrite: Boolean, sub: Sub? ): Either&lt;APIException, UpdateResult&gt;</ID>
<ID>LongMethod:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$@Transactional suspend fun partialUpdateEntityAttribute( entityId: URI, expandedPayload: Map&lt;String, List&lt;Map&lt;String, List&lt;Any&gt;&gt;&gt;&gt;, sub: Sub? ): Either&lt;APIException, UpdateResult&gt;</ID>
<ID>LongMethod:V0_29__JsonLd_migration.kt$V0_29__JsonLd_migration$override fun migrate(context: Context)</ID>
<ID>LongParameterList:AttributeInstance.kt$AttributeInstance.Companion$( temporalEntityAttribute: UUID, instanceId: URI? = null, timeProperty: TemporalProperty, time: ZonedDateTime, value: String? = null, measuredValue: Double? = null, geoValue: WKTCoordinates? = null, payload: ExpandedAttributePayloadEntry, sub: String? = null )</ID>
<ID>LongParameterList:EntityEventService.kt$EntityEventService$( sub: String?, entityId: URI, attributeName: String, datasetId: URI? = null, deleteAll: Boolean, contexts: List&lt;String&gt; )</ID>
<ID>LongParameterList:AttributeInstance.kt$AttributeInstance.Companion$( temporalEntityAttribute: UUID, instanceId: URI? = null, timeProperty: TemporalProperty, time: ZonedDateTime, value: String? = null, measuredValue: Double? = null, geoValue: WKTCoordinates? = null, payload: ExpandedAttributeInstance, sub: String? = null )</ID>
<ID>LongParameterList:EntityEventService.kt$EntityEventService$( sub: String?, entityId: URI, attributeName: ExpandedTerm, datasetId: URI? = null, deleteAll: Boolean, contexts: List&lt;String&gt; )</ID>
<ID>LongParameterList:EntityEventService.kt$EntityEventService$( sub: String?, entityId: URI, jsonLdAttributes: Map&lt;String, Any&gt;, updateResult: UpdateResult, overwrite: Boolean, contexts: List&lt;String&gt; )</ID>
<ID>LongParameterList:EntityHandler.kt$EntityHandler$( private val applicationProperties: ApplicationProperties, private val entityPayloadService: EntityPayloadService, private val temporalEntityAttributeService: TemporalEntityAttributeService, private val queryService: QueryService, private val authorizationService: AuthorizationService, private val entityAccessRightsService: EntityAccessRightsService, private val entityEventService: EntityEventService )</ID>
<ID>LongParameterList:EntityPayloadService.kt$EntityPayloadService$( entityId: URI, types: List&lt;ExpandedTerm&gt;, createdAt: ZonedDateTime, entityPayload: String, contexts: List&lt;String&gt;, specificAccessPolicy: SpecificAccessPolicy? = null )</ID>
<ID>LongParameterList:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$( entityId: URI, ngsiLdAttribute: NgsiLdAttribute, attributeMetadata: AttributeMetadata, createdAt: ZonedDateTime, attributePayload: ExpandedAttributePayloadEntry, sub: Sub? )</ID>
<ID>LongParameterList:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$( temporalEntityAttribute: TemporalEntityAttribute, ngsiLdAttribute: NgsiLdAttribute, attributeMetadata: AttributeMetadata, createdAt: ZonedDateTime, attributePayload: ExpandedAttributePayloadEntry, sub: Sub? )</ID>
<ID>LongParameterList:V0_29__JsonLd_migration.kt$V0_29__JsonLd_migration$( entityId: URI, attributeName: ExpandedTerm, datasetId: URI?, attributePayload: ExpandedAttributePayloadEntry, ngsiLdAttributeInstance: NgsiLdAttributeInstance, defaultCreatedAt: ZonedDateTime )</ID>
<ID>LongParameterList:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$( entityId: URI, ngsiLdAttribute: NgsiLdAttribute, attributeMetadata: AttributeMetadata, createdAt: ZonedDateTime, attributePayload: ExpandedAttributeInstance, sub: Sub? )</ID>
<ID>LongParameterList:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$( entityUri: URI, ngsiLdAttributes: List&lt;NgsiLdAttribute&gt;, jsonLdAttributes: Map&lt;String, Any&gt;, disallowOverwrite: Boolean, createdAt: ZonedDateTime, sub: Sub? )</ID>
<ID>LongParameterList:TemporalEntityAttributeService.kt$TemporalEntityAttributeService$( temporalEntityAttribute: TemporalEntityAttribute, ngsiLdAttribute: NgsiLdAttribute, attributeMetadata: AttributeMetadata, createdAt: ZonedDateTime, attributePayload: ExpandedAttributeInstance, sub: Sub? )</ID>
<ID>LongParameterList:V0_29__JsonLd_migration.kt$V0_29__JsonLd_migration$( entityId: URI, attributeName: ExpandedTerm, datasetId: URI?, attributePayload: ExpandedAttributeInstance, ngsiLdAttributeInstance: NgsiLdAttributeInstance, defaultCreatedAt: ZonedDateTime )</ID>
<ID>NestedBlockDepth:V0_29__JsonLd_migration.kt$V0_29__JsonLd_migration$override fun migrate(context: Context)</ID>
<ID>SwallowedException:QueryUtils.kt$e: IllegalArgumentException</ID>
<ID>ThrowsCount:QueryUtils.kt$fun buildTemporalQuery(params: MultiValueMap&lt;String, String&gt;, inQueryEntities: Boolean = false): TemporalQuery</ID>
<ID>TooManyFunctions:EntityPayloadService.kt$EntityPayloadService</ID>
<ID>TooManyFunctions:TemporalEntityAttributeService.kt$TemporalEntityAttributeService</ID>
<ID>UtilityClassWithPublicConstructor:ParameterizedTests.kt$ParameterizedTests</ID>
<ID>UtilityClassWithPublicConstructor:QueryParameterizedTests.kt$QueryParameterizedTests</ID>
Expand Down
19 changes: 12 additions & 7 deletions search-service/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '3.5'
version: '3.9'
services:
kafka:
image: confluentinc/cp-kafka:7.2.0
image: confluentinc/cp-kafka:7.3.1
container_name: stellio-kafka
hostname: stellio-kafka
ports:
Expand All @@ -22,19 +22,24 @@ services:
- ../config/kafka/update_run.sh:/tmp/update_run.sh
command: "bash -c 'if [ ! -f /tmp/update_run.sh ]; then echo \"ERROR: Did you forget the update_run.sh file that came with this docker-compose.yml file?\" && exit 1 ; else /tmp/update_run.sh && /etc/confluent/docker/run ; fi'"
postgres:
image: stellio/postgis:14-3.3-timescale
image: stellio/stellio-timescale-postgis:14-2.9.1-3.3
container_name: stellio-postgres
environment:
- DATADIR=/var/lib/postgresql/data
- POSTGRES_TEMPLATE_EXTENSIONS=true
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASS=${POSTGRES_PASS}
- POSTGRES_DBNAME=stellio_search
- POSTGRES_MULTIPLE_EXTENSIONS=postgis,hstore,postgis_topology,postgis_raster,pgrouting,timescaledb,pgcrypto
- POSTGRES_MULTIPLE_EXTENSIONS=postgis,timescaledb,pgcrypto
- ACCEPT_TIMESCALE_TUNING=TRUE
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U stellio"]
interval: 10s
timeout: 5s
retries: 20
start_period: 10s
volumes:
- stellio-search-postgres-storage:/var/lib/postgresql/data
- stellio-search-postgres-storage:/var/lib/postgresql

volumes:
stellio-search-postgres-storage:
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ interface AuthorizationService {
suspend fun userCanReadEntity(entityId: URI, sub: Option<Sub>): Either<APIException, Unit>
suspend fun userCanUpdateEntity(entityId: URI, sub: Option<Sub>): Either<APIException, Unit>
suspend fun userCanAdminEntity(entityId: URI, sub: Option<Sub>): Either<APIException, Unit>
suspend fun createAdminLink(entityId: URI, sub: Option<Sub>): Either<APIException, Unit>
suspend fun createAdminLinks(entitiesId: List<URI>, sub: Option<Sub>): Either<APIException, Unit>

suspend fun createAdminRight(entityId: URI, sub: Option<Sub>): Either<APIException, Unit>
suspend fun createAdminRights(entitiesId: List<URI>, sub: Option<Sub>): Either<APIException, Unit>
suspend fun removeRightsOnEntity(entityId: URI): Either<APIException, Unit>

suspend fun getAuthorizedEntities(
queryParams: QueryParams,
context: String,
sub: Option<Sub>,
sub: Option<Sub>
): Either<APIException, Pair<Int, List<JsonLdEntity>>>

suspend fun getGroupsMemberships(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ class DisabledAuthorizationService : AuthorizationService {
override suspend fun userCanAdminEntity(entityId: URI, sub: Option<Sub>): Either<APIException, Unit> =
Unit.right()

override suspend fun createAdminLink(entityId: URI, sub: Option<Sub>): Either<APIException, Unit> =
override suspend fun createAdminRight(entityId: URI, sub: Option<Sub>): Either<APIException, Unit> =
Unit.right()

override suspend fun createAdminLinks(
override suspend fun createAdminRights(
entitiesId: List<URI>,
sub: Option<Sub>
): Either<APIException, Unit> = Unit.right()

override suspend fun removeRightsOnEntity(entityId: URI): Either<APIException, Unit> = Unit.right()

override suspend fun getAuthorizedEntities(
queryParams: QueryParams,
context: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,17 @@ class EnabledAuthorizationService(
rights
)

override suspend fun createAdminLink(entityId: URI, sub: Option<Sub>): Either<APIException, Unit> =
createAdminLinks(listOf(entityId), sub)
override suspend fun createAdminRight(entityId: URI, sub: Option<Sub>): Either<APIException, Unit> =
createAdminRights(listOf(entityId), sub)

override suspend fun createAdminLinks(entitiesId: List<URI>, sub: Option<Sub>): Either<APIException, Unit> =
override suspend fun createAdminRights(entitiesId: List<URI>, sub: Option<Sub>): Either<APIException, Unit> =
entitiesId.parTraverseEither {
entityAccessRightsService.setAdminRoleOnEntity((sub as Some).value, it)
}.map { it.first() }

override suspend fun removeRightsOnEntity(entityId: URI): Either<APIException, Unit> =
entityAccessRightsService.removeRolesOnEntity(entityId)

override suspend fun getAuthorizedEntities(
queryParams: QueryParams,
context: String,
Expand Down Expand Up @@ -130,7 +133,7 @@ class EnabledAuthorizationService(
val count = entityAccessRightsService.getSubjectAccessRightsCount(
sub,
accessRights,
queryParams.types,
queryParams.types
).bind()

Pair(count, entitiesAccessControlWithSubjectRights)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ data class EntityAccessRights(
) {
val datasetId: URI = (DATASET_ID_PREFIX + uri.extractSub()).toUri()

fun serializeProperties(): ExpandedAttributePayload =
fun serializeProperties(): ExpandedAttributeInstances =
buildExpandedRelationship(uri)
.addSubAttribute(NGSILD_DATASET_ID_PROPERTY, buildNonReifiedProperty(datasetId.toString()))
.addSubAttribute(AUTH_PROP_SUBJECT_INFO, buildExpandedSubjectInfo(subjectInfo))
Expand Down Expand Up @@ -100,7 +100,7 @@ data class EntityAccessRights(
* }
* ]
*/
private fun buildExpandedSubjectInfo(value: Map<String, String>): ExpandedAttributePayload =
private fun buildExpandedSubjectInfo(value: Map<String, String>): ExpandedAttributeInstances =
listOf(
mapOf(
JSONLD_TYPE to listOf(NGSILD_PROPERTY_TYPE.uri),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ class EntityAccessRightsService(
else it
}
.allToMappedList { rowToEntityAccessControl(it, isStellioAdmin) }
.groupBy { it.id }
// a user may have multiple rights on a given entity (e.g., through groups memberships)
// retain the one with the "higher" right
.mapValues {
val ear = it.value.first()
EntityAccessRights(
ear.id,
ear.types,
it.value.maxOf { it.right },
ear.specificAccessPolicy
)
}.values.toList()
}

suspend fun getSubjectAccessRightsCount(
Expand Down
Loading

0 comments on commit 205687a

Please sign in to comment.