-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add organization deletion route #4298
Conversation
dcb4f83
to
b90801e
Compare
Failing test is just to do with how we respond when |
...sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleter.scala
Outdated
Show resolved
Hide resolved
...sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleter.scala
Outdated
Show resolved
Hide resolved
} yield () | ||
|
||
private def deleteGlobalQuery(id: IriOrBNode.Iri, tpe: EntityType, table: String): ConnectionIO[Unit] = | ||
Update[(EntityType, IriOrBNode.Iri)](s"DELETE FROM $table WHERE" ++ " type = ? AND id = ?").run((tpe, id)).void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the sql interpolator here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not possible when parameterising over the table name since substitutions only work for values. This is maybe a bit overkill but I was curious to see if it was possible 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fragment.const
could also help here ? (not sure)
...src/test/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleterSpec.scala
Outdated
Show resolved
Hide resolved
...src/test/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleterSpec.scala
Outdated
Show resolved
Hide resolved
...src/test/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleterSpec.scala
Outdated
Show resolved
Hide resolved
...src/test/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleterSpec.scala
Outdated
Show resolved
Hide resolved
delta/sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/acls/Acls.scala
Outdated
Show resolved
Hide resolved
I am ok with that
Nothing to do with the permission itself but we will need to assign it to a user to test it
Not sure we can do much better with this kind of PR but as this part is mostly independent from the rest, you may have opted for Cats-Effect in the end :) .
There is definitely room to improve things by making the code more modular, by improving the way we use MUnit (like setting up CE Resources and transform to MUnit fixtures the latest possible as those don't compose), by designing how to test the lifecycle of a resource without too much repetition and slowing them down too much... |
delta/app/src/main/scala/ch/epfl/bluebrain/nexus/delta/routes/OrganizationsRoutes.scala
Outdated
Show resolved
Hide resolved
...src/test/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/OrganizationDeleterSpec.scala
Outdated
Show resolved
Hide resolved
8a3b232
to
e3564a1
Compare
...main/scala/ch/epfl/bluebrain/nexus/delta/sdk/organizations/model/OrganizationRejection.scala
Outdated
Show resolved
Hide resolved
delta/sdk/src/main/scala/ch/epfl/bluebrain/nexus/delta/sdk/permissions/Permissions.scala
Outdated
Show resolved
Hide resolved
|
||
private lazy val orgs = OrganizationsImpl(Set(aopd), config, xas) | ||
private lazy val orgDeleter: OrganizationDeleter = id => | ||
if (id == org1.label) IO.raiseError(OrganizationNonEmpty(id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IO.raiseWhen
would make it shorter
) { | ||
)(implicit s: Scheduler) { | ||
|
||
def readCE: Transactor[IO] = read.mapK(BIO.liftTo) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice that something like this is possible
@@ -123,6 +123,12 @@ Creating an archive now requires only the `resources/read` permission instead of | |||
|
|||
Tarball archives are no longer supported due to unnecessary restrictions. ZIP is now the only allowed format and clients should send `application/zip` in the `Accept` header when creating archives. | |||
|
|||
### Organizations | |||
|
|||
#### Support deletion of empty organizations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Link to the operation in the API ?
Key implementation points:
prune
parameter toDELETE /orgs/{label}
defaulting to false and requiring a neworganizations/delete
permission. Previously only deprecation was allowed for a specificrev
. Not sure how great it is to ignorerev
even if specified, maybe slightly confusing for the client? If the org is empty, return 409 Conflict.OrganizationDeleter
has all the logic. If the org is non-empty, we do these stepsI used this ticket to try to understand some of the patterns in the codebase so I have a few questions / comments, some specific to this and some more general:
Acls
, is this ok? The main reason was so it could all be in one transaction, since this feels like a bad thing to get stuck in a half-way state. It would also add a bigger dependency.Any
grimness. Is there a better way?