mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 10:28:27 +00:00
Add route to get settings for a share
Returns the client settings of the creator.
This commit is contained in:
@ -48,6 +48,8 @@ trait OShare[F[_]] {
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
|
def findActiveById(id: Ident): OptionT[F, ShareData]
|
||||||
|
|
||||||
/** Verifies the given id and password and returns a authorization token on success. */
|
/** Verifies the given id and password and returns a authorization token on success. */
|
||||||
def verify(key: ByteVector)(id: Ident, password: Option[Password]): F[VerifyResult]
|
def verify(key: ByteVector)(id: Ident, password: Option[Password]): F[VerifyResult]
|
||||||
|
|
||||||
@ -277,6 +279,9 @@ object OShare {
|
|||||||
VerifyResult.invalidToken.pure[F]
|
VerifyResult.invalidToken.pure[F]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def findActiveById(id: Ident): OptionT[F, ShareData] =
|
||||||
|
RShare.findCurrentActive(id).mapK(store.transform).map(ShareData.tupled)
|
||||||
|
|
||||||
def findShareQuery(id: Ident): OptionT[F, ShareQuery] =
|
def findShareQuery(id: Ident): OptionT[F, ShareQuery] =
|
||||||
RShare
|
RShare
|
||||||
.findCurrentActive(id)
|
.findCurrentActive(id)
|
||||||
|
@ -2304,7 +2304,7 @@ paths:
|
|||||||
/share/attachment/{id}/preview:
|
/share/attachment/{id}/preview:
|
||||||
head:
|
head:
|
||||||
operationId: "share-attach-check-preview"
|
operationId: "share-attach-check-preview"
|
||||||
tags: [ Attachment ]
|
tags: [ Share ]
|
||||||
summary: Get the headers to a preview image of an attachment file.
|
summary: Get the headers to a preview image of an attachment file.
|
||||||
description: |
|
description: |
|
||||||
Checks if an image file showing a preview of the attachment is
|
Checks if an image file showing a preview of the attachment is
|
||||||
@ -2320,7 +2320,7 @@ paths:
|
|||||||
description: NotFound
|
description: NotFound
|
||||||
get:
|
get:
|
||||||
operationId: "share-attach-get-preview"
|
operationId: "share-attach-get-preview"
|
||||||
tags: [ Attachment ]
|
tags: [ Share ]
|
||||||
summary: Get a preview image of an attachment file.
|
summary: Get a preview image of an attachment file.
|
||||||
description: |
|
description: |
|
||||||
Gets a image file showing a preview of the attachment. Usually
|
Gets a image file showing a preview of the attachment. Usually
|
||||||
@ -2347,6 +2347,37 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: binary
|
format: binary
|
||||||
|
/share/clientSettings/{clientId}:
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/clientId"
|
||||||
|
get:
|
||||||
|
operationId: "share-clientsettings-get"
|
||||||
|
tags: [ Share ]
|
||||||
|
summary: Return the client settings of current user
|
||||||
|
description: |
|
||||||
|
Returns the settings for the share. This is the settings of
|
||||||
|
the user who created the share. It is created by merging the
|
||||||
|
client settings for the collective and the user's own client
|
||||||
|
settings into one json structure.
|
||||||
|
|
||||||
|
Null, Array, Boolean, String and Number are treated as values,
|
||||||
|
and values from the users settings completely replace values
|
||||||
|
from the collective's settings.
|
||||||
|
|
||||||
|
The `clientId` is an identifier to a client application. It
|
||||||
|
returns a JSON structure. The server doesn't care about the
|
||||||
|
actual data, since it is meant to be interpreted by clients.
|
||||||
|
security:
|
||||||
|
- shareTokenHeader: []
|
||||||
|
responses:
|
||||||
|
422:
|
||||||
|
description: BadRequest
|
||||||
|
200:
|
||||||
|
description: Ok
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema: {}
|
||||||
|
|
||||||
|
|
||||||
/admin/user/resetPassword:
|
/admin/user/resetPassword:
|
||||||
post:
|
post:
|
||||||
|
@ -213,7 +213,8 @@ object RestServer {
|
|||||||
Router(
|
Router(
|
||||||
"search" -> ShareSearchRoutes(restApp.backend, cfg, token),
|
"search" -> ShareSearchRoutes(restApp.backend, cfg, token),
|
||||||
"attachment" -> ShareAttachmentRoutes(restApp.backend, token),
|
"attachment" -> ShareAttachmentRoutes(restApp.backend, token),
|
||||||
"item" -> ShareItemRoutes(restApp.backend, token)
|
"item" -> ShareItemRoutes(restApp.backend, token),
|
||||||
|
"clientSettings" -> ClientSettingsRoutes.share(restApp.backend, token)
|
||||||
)
|
)
|
||||||
|
|
||||||
def redirectTo[F[_]: Async](path: String): HttpRoutes[F] = {
|
def redirectTo[F[_]: Async](path: String): HttpRoutes[F] = {
|
||||||
|
@ -8,10 +8,11 @@ package docspell.restserver.routes
|
|||||||
|
|
||||||
import cats.effect._
|
import cats.effect._
|
||||||
import cats.implicits._
|
import cats.implicits._
|
||||||
import cats.kernel.Semigroup
|
import cats.{Monad, Semigroup}
|
||||||
|
import cats.data.OptionT
|
||||||
|
|
||||||
import docspell.backend.BackendApp
|
import docspell.backend.BackendApp
|
||||||
import docspell.backend.auth.AuthToken
|
import docspell.backend.auth.{AuthToken, ShareToken}
|
||||||
import docspell.common._
|
import docspell.common._
|
||||||
import docspell.restapi.model._
|
import docspell.restapi.model._
|
||||||
|
|
||||||
@ -23,6 +24,30 @@ import org.http4s.dsl.Http4sDsl
|
|||||||
|
|
||||||
object ClientSettingsRoutes {
|
object ClientSettingsRoutes {
|
||||||
|
|
||||||
|
def share[F[_]: Async](
|
||||||
|
backend: BackendApp[F],
|
||||||
|
token: ShareToken
|
||||||
|
): HttpRoutes[F] = {
|
||||||
|
val logger = Logger.log4s[F](org.log4s.getLogger)
|
||||||
|
|
||||||
|
val dsl = new Http4sDsl[F] {}
|
||||||
|
import dsl._
|
||||||
|
|
||||||
|
HttpRoutes.of {
|
||||||
|
case GET -> Root / Ident(clientId) =>
|
||||||
|
(for {
|
||||||
|
_ <- OptionT.liftF(logger.debug(s"Get client settings for share ${token.id}"))
|
||||||
|
share <- backend.share.findActiveById(token.id)
|
||||||
|
merged <- OptionT.liftF(getMergedSettings(backend, share.user.accountId, clientId))
|
||||||
|
res <- OptionT.liftF(merged match {
|
||||||
|
case Some(j) => Ok(j)
|
||||||
|
case None => NotFound()
|
||||||
|
})
|
||||||
|
} yield res)
|
||||||
|
.getOrElseF(Ok(Map.empty[String, String]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def apply[F[_]: Async](backend: BackendApp[F], user: AuthToken): HttpRoutes[F] = {
|
def apply[F[_]: Async](backend: BackendApp[F], user: AuthToken): HttpRoutes[F] = {
|
||||||
val dsl = new Http4sDsl[F] {}
|
val dsl = new Http4sDsl[F] {}
|
||||||
import dsl._
|
import dsl._
|
||||||
@ -30,10 +55,7 @@ object ClientSettingsRoutes {
|
|||||||
HttpRoutes.of {
|
HttpRoutes.of {
|
||||||
case GET -> Root / Ident(clientId) =>
|
case GET -> Root / Ident(clientId) =>
|
||||||
for {
|
for {
|
||||||
collData <- backend.clientSettings.loadCollective(clientId, user.account)
|
mergedData <- getMergedSettings(backend, user.account, clientId)
|
||||||
userData <- backend.clientSettings.loadUser(clientId, user.account)
|
|
||||||
|
|
||||||
mergedData = collData.map(_.settingsData) |+| userData.map(_.settingsData)
|
|
||||||
|
|
||||||
res <- mergedData match {
|
res <- mergedData match {
|
||||||
case Some(j) => Ok(j)
|
case Some(j) => Ok(j)
|
||||||
@ -97,6 +119,16 @@ object ClientSettingsRoutes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def getMergedSettings[F[_]: Monad](backend:BackendApp[F], account: AccountId, clientId: Ident) =
|
||||||
|
for {
|
||||||
|
collData <- backend.clientSettings.loadCollective(clientId, account)
|
||||||
|
userData <- backend.clientSettings.loadUser(clientId, account)
|
||||||
|
|
||||||
|
mergedData = collData.map(_.settingsData) |+| userData.map(_.settingsData)
|
||||||
|
} yield mergedData
|
||||||
|
|
||||||
|
|
||||||
implicit def jsonSemigroup: Semigroup[Json] =
|
implicit def jsonSemigroup: Semigroup[Json] =
|
||||||
Semigroup.instance((a1, a2) => a1.deepMerge(a2))
|
Semigroup.instance((a1, a2) => a1.deepMerge(a2))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user