Basic management of shares

This commit is contained in:
eikek
2021-10-02 15:16:02 +02:00
parent de1baf725f
commit c7d587bea4
27 changed files with 1551 additions and 20 deletions

View File

@ -48,6 +48,7 @@ trait BackendApp[F[_]] {
def simpleSearch: OSimpleSearch[F]
def clientSettings: OClientSettings[F]
def totp: OTotp[F]
def share: OShare[F]
}
object BackendApp {
@ -85,6 +86,7 @@ object BackendApp {
customFieldsImpl <- OCustomFields(store)
simpleSearchImpl = OSimpleSearch(fulltextImpl, itemSearchImpl)
clientSettingsImpl <- OClientSettings(store)
shareImpl <- Resource.pure(OShare(store))
} yield new BackendApp[F] {
val login = loginImpl
val signup = signupImpl
@ -107,6 +109,7 @@ object BackendApp {
val simpleSearch = simpleSearchImpl
val clientSettings = clientSettingsImpl
val totp = totpImpl
val share = shareImpl
}
def apply[F[_]: Async](

View File

@ -0,0 +1,116 @@
/*
* Copyright 2020 Eike K. & Contributors
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package docspell.backend.ops
import cats.data.OptionT
import cats.effect._
import cats.implicits._
import docspell.backend.PasswordCrypt
import docspell.common._
import docspell.query.ItemQuery
import docspell.store.Store
import docspell.store.records.RShare
trait OShare[F[_]] {
def findAll(collective: Ident): F[List[RShare]]
def delete(id: Ident, collective: Ident): F[Boolean]
def addNew(share: OShare.NewShare): F[OShare.ChangeResult]
def findOne(id: Ident, collective: Ident): OptionT[F, RShare]
def update(
id: Ident,
share: OShare.NewShare,
removePassword: Boolean
): F[OShare.ChangeResult]
}
object OShare {
final case class NewShare(
cid: Ident,
name: Option[String],
query: ItemQuery,
enabled: Boolean,
password: Option[Password],
publishUntil: Timestamp
)
sealed trait ChangeResult
object ChangeResult {
final case class Success(id: Ident) extends ChangeResult
case object PublishUntilInPast extends ChangeResult
def success(id: Ident): ChangeResult = Success(id)
def publishUntilInPast: ChangeResult = PublishUntilInPast
}
def apply[F[_]: Async](store: Store[F]): OShare[F] =
new OShare[F] {
def findAll(collective: Ident): F[List[RShare]] =
store.transact(RShare.findAllByCollective(collective))
def delete(id: Ident, collective: Ident): F[Boolean] =
store.transact(RShare.deleteByIdAndCid(id, collective)).map(_ > 0)
def addNew(share: NewShare): F[ChangeResult] =
for {
curTime <- Timestamp.current[F]
id <- Ident.randomId[F]
pass = share.password.map(PasswordCrypt.crypt)
record = RShare(
id,
share.cid,
share.name,
share.query,
share.enabled,
pass,
curTime,
share.publishUntil,
0,
None
)
res <-
if (share.publishUntil < curTime) ChangeResult.publishUntilInPast.pure[F]
else store.transact(RShare.insert(record)).map(_ => ChangeResult.success(id))
} yield res
def update(
id: Ident,
share: OShare.NewShare,
removePassword: Boolean
): F[ChangeResult] =
for {
curTime <- Timestamp.current[F]
record = RShare(
id,
share.cid,
share.name,
share.query,
share.enabled,
share.password.map(PasswordCrypt.crypt),
Timestamp.Epoch,
share.publishUntil,
0,
None
)
res <-
if (share.publishUntil < curTime) ChangeResult.publishUntilInPast.pure[F]
else
store
.transact(RShare.updateData(record, removePassword))
.map(_ => ChangeResult.success(id))
} yield res
def findOne(id: Ident, collective: Ident): OptionT[F, RShare] =
RShare.findOne(id, collective).mapK(store.transform)
}
}