mirror of
				https://github.com/TheAnachronism/docspell.git
				synced 2025-10-30 21:40:12 +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. */ | ||||
|   def verify(key: ByteVector)(id: Ident, password: Option[Password]): F[VerifyResult] | ||||
|  | ||||
| @@ -277,6 +279,9 @@ object OShare { | ||||
|               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] = | ||||
|         RShare | ||||
|           .findCurrentActive(id) | ||||
|   | ||||
| @@ -2304,7 +2304,7 @@ paths: | ||||
|   /share/attachment/{id}/preview: | ||||
|     head: | ||||
|       operationId: "share-attach-check-preview" | ||||
|       tags: [ Attachment ] | ||||
|       tags: [ Share ] | ||||
|       summary: Get the headers to a preview image of an attachment file. | ||||
|       description: | | ||||
|         Checks if an image file showing a preview of the attachment is | ||||
| @@ -2320,7 +2320,7 @@ paths: | ||||
|           description: NotFound | ||||
|     get: | ||||
|       operationId: "share-attach-get-preview" | ||||
|       tags: [ Attachment ] | ||||
|       tags: [ Share ] | ||||
|       summary: Get a preview image of an attachment file. | ||||
|       description: | | ||||
|         Gets a image file showing a preview of the attachment. Usually | ||||
| @@ -2347,6 +2347,37 @@ paths: | ||||
|               schema: | ||||
|                 type: string | ||||
|                 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: | ||||
|     post: | ||||
|   | ||||
| @@ -213,7 +213,8 @@ object RestServer { | ||||
|     Router( | ||||
|       "search" -> ShareSearchRoutes(restApp.backend, cfg, 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] = { | ||||
|   | ||||
| @@ -8,10 +8,11 @@ package docspell.restserver.routes | ||||
|  | ||||
| import cats.effect._ | ||||
| import cats.implicits._ | ||||
| import cats.kernel.Semigroup | ||||
| import cats.{Monad, Semigroup} | ||||
| import cats.data.OptionT | ||||
|  | ||||
| import docspell.backend.BackendApp | ||||
| import docspell.backend.auth.AuthToken | ||||
| import docspell.backend.auth.{AuthToken, ShareToken} | ||||
| import docspell.common._ | ||||
| import docspell.restapi.model._ | ||||
|  | ||||
| @@ -23,6 +24,30 @@ import org.http4s.dsl.Http4sDsl | ||||
|  | ||||
| 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] = { | ||||
|     val dsl = new Http4sDsl[F] {} | ||||
|     import dsl._ | ||||
| @@ -30,10 +55,7 @@ object ClientSettingsRoutes { | ||||
|     HttpRoutes.of { | ||||
|       case GET -> Root / Ident(clientId) => | ||||
|         for { | ||||
|           collData <- backend.clientSettings.loadCollective(clientId, user.account) | ||||
|           userData <- backend.clientSettings.loadUser(clientId, user.account) | ||||
|  | ||||
|           mergedData = collData.map(_.settingsData) |+| userData.map(_.settingsData) | ||||
|           mergedData <- getMergedSettings(backend, user.account, clientId) | ||||
|  | ||||
|           res <- mergedData match { | ||||
|             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] = | ||||
|     Semigroup.instance((a1, a2) => a1.deepMerge(a2)) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user