All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
sss.openstar.attachments.LocalAttachmentsService.scala Maven / Gradle / Ivy
package sss.openstar.attachments
import java.io.InputStream
import java.sql.SQLIntegrityConstraintViolationException
import sss.ancillary.Guid
import sss.db._
import sss.openstar.attachments.AttachmentsService.EncryptedAttachment
import sss.openstar.crypto.AESDetails.AESEncodedKey
import sss.openstar.crypto.{CBCEncryption, CBCStreamEncryption}
import scala.util.Try
import sss.openstar.schemamigration.SqlSchemaNames.ColumnNames._
import sss.db.ops.DbOps.{DbRunOps, FutureTxOps}
import sss.openstar.schemamigration.SqlSchemaNames
class LocalAttachmentsService(
streamPersister: StreamPersister
)(implicit db: Db) {
private[attachments] val table = db.table(SqlSchemaNames.TableNames.attachmentsTableName)
def forUser(who: String): LocalAttachments = new LocalAttachments(who, streamPersister, this)
def find(
guid: Guid,
name: String): Option[EncryptedAttachment] = {
table.find(
where(
nameCol -> name,
guidCol -> guid.value
//ownerCol -> who
)
).dbRunSyncGet.map(row => {
val inputStream = streamPersister
.getStream(
UniqueLocator(row.string(locationUrlCol)))
.get
EncryptedAttachment(
inputStream,
Guid(row.arrayByte(guidCol)),
row.string(nameCol),
row.string(mimeCol),
row.long(lenCol),
CBCEncryption.initVector(row.arrayByte(ivKeyCol)))
})
}
}
class LocalAttachments(
who:String,
streamPersister: StreamPersister,
service:LocalAttachmentsService)(implicit db: Db) {
require(Option(who).isDefined && who.length > 0, "User must not be null or empty")
val table = service.table
def delete(guid: Guid, name: String): Try[Int] = {
table.delete(
where(
guidCol -> guid.value,
nameCol -> name
)
)
}.dbRunSync
def delete(guid: Guid): Try[Int] = {
table.delete(
where(
guidCol -> guid.value,
)
)
}.dbRunSync
def filter(
guid: Guid,
lenLessThan: Long = Long.MaxValue): Seq[EncryptedAttachment] = {
table.filter(
where(
guidCol -> guid.value,
ownerCol -> who
) and where(s"$lenCol < $lenLessThan")
).dbRunSyncGet.map(row => {
val is = streamPersister.getStream(
UniqueLocator(
row.string(locationUrlCol)))
.get
EncryptedAttachment(
is,
Guid(row.arrayByte(guidCol)),
row.string(nameCol),
row.string(mimeCol),
row.long(lenCol),
CBCEncryption.initVector(row.arrayByte(ivKeyCol)))
})
}
def find(
guid: Guid,
name: String): Option[EncryptedAttachment] = service.find(guid, name)
def saveEncrypted(guid: Guid,
name: String,
mimeType: String,
key: AESEncodedKey,
clearInputStream: InputStream
): Try[Long] = Try {
val encryptedStream = CBCStreamEncryption.encrypt(clearInputStream, key)
val locator = streamPersister.saveStream(encryptedStream.encrypted, who, guid.toString, name).get
(locator, encryptedStream)
}.flatMap {
case (locator, encryptedStream) =>
table.insert(Map(
guidCol -> guid.value,
nameCol -> name,
ownerCol -> who,
mimeCol -> mimeType,
ivKeyCol -> encryptedStream.iv.bytes,
lenCol -> locator.size.getOrElse(0),
locationUrlCol -> locator.location
)).recoverWithDb {
case _: SQLIntegrityConstraintViolationException =>
table.update(Map(
ivKeyCol -> encryptedStream.iv.bytes,
lenCol -> locator.size.getOrElse(0),
locationUrlCol -> locator.location
), where(
guidCol -> guid.value,
nameCol -> name,
ownerCol -> who
))
}.dbRunSync.map[Long](_ => locator.size.getOrElse(0))
}
}