diff --git a/modules/restapi/src/main/resources/docspell-openapi.yml b/modules/restapi/src/main/resources/docspell-openapi.yml index 394aa91d..f5da45e6 100644 --- a/modules/restapi/src/main/resources/docspell-openapi.yml +++ b/modules/restapi/src/main/resources/docspell-openapi.yml @@ -1584,9 +1584,9 @@ paths: $ref: "#/components/schemas/BasicResult" /sec/user/{username}: delete: - operationId: "sec-user-delete-by-username" + operationId: "sec-user-delete-by-userid-or-login" tags: [ Collective ] - summary: Delete a user. + summary: Delete a user by its id or login name. description: | Deletes a user. security: diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/UserRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/UserRoutes.scala index 243e26b9..a3f84aff 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/UserRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/UserRoutes.scala @@ -6,6 +6,7 @@ package docspell.restserver.routes +import cats.data.OptionT import cats.effect._ import cats.implicits._ @@ -73,8 +74,13 @@ object UserRoutes { for { users <- backend.collective.listUser(user.account.collectiveId) ar <- - if (users.exists(_.uid == id)) backend.collective.deleteUser(id) - else UpdateResult.notFound.pure[F] + OptionT + .fromOption[F]( + users + .find(u => u.uid == id || u.login == id) + ) + .semiflatMap(u => backend.collective.deleteUser(u.uid)) + .getOrElse(UpdateResult.notFound) resp <- Ok(basicResult(ar, "User deleted.")) } yield resp diff --git a/modules/store/src/main/scala/docspell/store/qb/impl/FromExprBuilder.scala b/modules/store/src/main/scala/docspell/store/qb/impl/FromExprBuilder.scala index 65860ad4..5b9f0290 100644 --- a/modules/store/src/main/scala/docspell/store/qb/impl/FromExprBuilder.scala +++ b/modules/store/src/main/scala/docspell/store/qb/impl/FromExprBuilder.scala @@ -25,7 +25,7 @@ object FromExprBuilder { def buildTable(table: TableDef): Fragment = Fragment.const(table.tableName) ++ table.alias - .map(a => Fragment.const0(a)) + .map(a => Fragment.const(a)) .getOrElse(Fragment.empty) def buildRelation(rel: FromExpr.Relation): Fragment = diff --git a/modules/store/src/test/scala/docspell/store/qb/impl/DSLTest.scala b/modules/store/src/test/scala/docspell/store/qb/impl/DSLTest.scala index 2c672d62..7691fc76 100644 --- a/modules/store/src/test/scala/docspell/store/qb/impl/DSLTest.scala +++ b/modules/store/src/test/scala/docspell/store/qb/impl/DSLTest.scala @@ -17,6 +17,11 @@ class DSLTest extends FunSuite { val course = CourseRecord.as("c") val person = PersonRecord.as("p") + test("delete") { + val frag = DML.deleteFragment(course, course.ownerId === 15L) + assertEquals(frag.internals.sql, "DELETE FROM course c WHERE c.owner_id = ? ") + } + test("and") { val c = course.lessons > 4 && person.id === 3 && person.name.like("%a%") val expect = diff --git a/modules/store/src/test/scala/docspell/store/qb/impl/SelectBuilderTest.scala b/modules/store/src/test/scala/docspell/store/qb/impl/SelectBuilderTest.scala index 0ba3c7a5..4e16e5ef 100644 --- a/modules/store/src/test/scala/docspell/store/qb/impl/SelectBuilderTest.scala +++ b/modules/store/src/test/scala/docspell/store/qb/impl/SelectBuilderTest.scala @@ -32,8 +32,8 @@ class SelectBuilderTest extends FunSuite with TestLoggingConfig { val q = Select(proj, table, cond) val frag = SelectBuilder(q) assertEquals( - frag.toString, - """Fragment("SELECT c.id, c.name, c.owner_id, c.lecturer_id, c.lessons FROM course c INNER JOIN person o ON c.owner_id = o.id LEFT JOIN person l ON c.lecturer_id = l.id WHERE (LOWER(c.name) LIKE ? AND o.name = ? )")""" + frag.internals.sql, + """SELECT c.id, c.name, c.owner_id, c.lecturer_id, c.lessons FROM course c INNER JOIN person o ON c.owner_id = o.id LEFT JOIN person l ON c.lecturer_id = l.id WHERE (LOWER(c.name) LIKE ? AND o.name = ? )""" ) }