Add imap settings

This commit is contained in:
Eike Kettner
2020-05-05 22:48:08 +02:00
parent 2a5ffd391e
commit c9de74fd91
14 changed files with 1221 additions and 38 deletions

View File

@ -0,0 +1,14 @@
CREATE TABLE `userimap` (
`id` varchar(254) not null primary key,
`uid` varchar(254) not null,
`name` varchar(254) not null,
`imap_host` varchar(254) not null,
`imap_port` int,
`imap_user` varchar(254),
`imap_password` varchar(254),
`imap_ssl` varchar(254) not null,
`imap_certcheck` boolean not null,
`created` timestamp not null,
unique (`uid`, `name`),
foreign key (`uid`) references `user_`(`uid`)
);

View File

@ -0,0 +1,14 @@
CREATE TABLE "userimap" (
"id" varchar(254) not null primary key,
"uid" varchar(254) not null,
"name" varchar(254) not null,
"imap_host" varchar(254) not null,
"imap_port" int,
"imap_user" varchar(254),
"imap_password" varchar(254),
"imap_ssl" varchar(254) not null,
"imap_certcheck" boolean not null,
"created" timestamp not null,
unique ("uid", "name"),
foreign key ("uid") references "user_"("uid")
);

View File

@ -0,0 +1,201 @@
package docspell.store.records
import doobie._
import doobie.implicits._
import cats.effect._
import cats.implicits._
import cats.data.OptionT
import docspell.common._
import docspell.store.impl.Column
import docspell.store.impl.Implicits._
import emil.{MailConfig, SSLType}
case class RUserImap(
id: Ident,
uid: Ident,
name: Ident,
imapHost: String,
imapPort: Option[Int],
imapUser: Option[String],
imapPassword: Option[Password],
imapSsl: SSLType,
imapCertCheck: Boolean,
created: Timestamp
) {
def toMailConfig: MailConfig = {
val port = imapPort.map(p => s":$p").getOrElse("")
MailConfig(
s"imap://$imapHost$port",
imapUser.getOrElse(""),
imapPassword.map(_.pass).getOrElse(""),
imapSsl,
!imapCertCheck
)
}
}
object RUserImap {
def apply[F[_]: Sync](
uid: Ident,
name: Ident,
imapHost: String,
imapPort: Option[Int],
imapUser: Option[String],
imapPassword: Option[Password],
imapSsl: SSLType,
imapCertCheck: Boolean
): F[RUserImap] =
for {
now <- Timestamp.current[F]
id <- Ident.randomId[F]
} yield RUserImap(
id,
uid,
name,
imapHost,
imapPort,
imapUser,
imapPassword,
imapSsl,
imapCertCheck,
now
)
def fromAccount(
accId: AccountId,
name: Ident,
imapHost: String,
imapPort: Option[Int],
imapUser: Option[String],
imapPassword: Option[Password],
imapSsl: SSLType,
imapCertCheck: Boolean
): OptionT[ConnectionIO, RUserImap] =
for {
now <- OptionT.liftF(Timestamp.current[ConnectionIO])
id <- OptionT.liftF(Ident.randomId[ConnectionIO])
user <- OptionT(RUser.findByAccount(accId))
} yield RUserImap(
id,
user.uid,
name,
imapHost,
imapPort,
imapUser,
imapPassword,
imapSsl,
imapCertCheck,
now
)
val table = fr"userimap"
object Columns {
val id = Column("id")
val uid = Column("uid")
val name = Column("name")
val imapHost = Column("imap_host")
val imapPort = Column("imap_port")
val imapUser = Column("imap_user")
val imapPass = Column("imap_password")
val imapSsl = Column("imap_ssl")
val imapCertCheck = Column("imap_certcheck")
val created = Column("created")
val all = List(
id,
uid,
name,
imapHost,
imapPort,
imapUser,
imapPass,
imapSsl,
imapCertCheck,
created
)
}
import Columns._
def insert(v: RUserImap): ConnectionIO[Int] =
insertRow(
table,
all,
sql"${v.id},${v.uid},${v.name},${v.imapHost},${v.imapPort},${v.imapUser},${v.imapPassword},${v.imapSsl},${v.imapCertCheck},${v.created}"
).update.run
def update(eId: Ident, v: RUserImap): ConnectionIO[Int] =
updateRow(
table,
id.is(eId),
commas(
name.setTo(v.name),
imapHost.setTo(v.imapHost),
imapPort.setTo(v.imapPort),
imapUser.setTo(v.imapUser),
imapPass.setTo(v.imapPassword),
imapSsl.setTo(v.imapSsl),
imapCertCheck.setTo(v.imapCertCheck)
)
).update.run
def findByUser(userId: Ident): ConnectionIO[Vector[RUserImap]] =
selectSimple(all, table, uid.is(userId)).query[RUserImap].to[Vector]
private def findByAccount0(
accId: AccountId,
nameQ: Option[String],
exact: Boolean
): Query0[RUserImap] = {
val mUid = uid.prefix("m")
val mName = name.prefix("m")
val uId = RUser.Columns.uid.prefix("u")
val uColl = RUser.Columns.cid.prefix("u")
val uLogin = RUser.Columns.login.prefix("u")
val from = table ++ fr"m INNER JOIN" ++ RUser.table ++ fr"u ON" ++ mUid.is(uId)
val cond = Seq(uColl.is(accId.collective), uLogin.is(accId.user)) ++ (nameQ match {
case Some(str) if exact => Seq(mName.is(str))
case Some(str) if !exact => Seq(mName.lowerLike(s"%${str.toLowerCase}%"))
case None => Seq.empty
})
(selectSimple(all.map(_.prefix("m")), from, and(cond)) ++ orderBy(mName.f))
.query[RUserImap]
}
def findByAccount(
accId: AccountId,
nameQ: Option[String]
): ConnectionIO[Vector[RUserImap]] =
findByAccount0(accId, nameQ, false).to[Vector]
def getByName(accId: AccountId, name: Ident): ConnectionIO[Option[RUserImap]] =
findByAccount0(accId, Some(name.id), true).option
def delete(accId: AccountId, connName: Ident): ConnectionIO[Int] = {
val uId = RUser.Columns.uid
val uColl = RUser.Columns.cid
val uLogin = RUser.Columns.login
val cond = Seq(uColl.is(accId.collective), uLogin.is(accId.user))
deleteFrom(
table,
fr"uid in (" ++ selectSimple(Seq(uId), RUser.table, and(cond)) ++ fr") AND" ++ name
.is(
connName
)
).update.run
}
def exists(accId: AccountId, name: Ident): ConnectionIO[Boolean] =
getByName(accId, name).map(_.isDefined)
def exists(userId: Ident, connName: Ident): ConnectionIO[Boolean] =
selectCount(id, table, and(uid.is(userId), name.is(connName)))
.query[Int]
.unique
.map(_ > 0)
}