All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sss.openstar.attachments.RemoteAttachmentsService.scala Maven / Gradle / Ivy

package sss.openstar.attachments

import java.net.{HttpURLConnection, URL, URLConnection, URLEncoder}
import java.nio.charset.StandardCharsets

import sss.ancillary.FailWithException.fail
import sss.ancillary.{Guid, Logging}
import sss.openstar.UniqueNodeIdentifier
import sss.openstar.attachments.AttachmentsService.EncryptedAttachment
import sss.openstar.attachments.RemoteAttachmentsService._
import sss.openstar.attachments.RemoteAttachmentsServlet._
import sss.openstar.crypto.CBCEncryption

import scala.util.{Failure, Success, Try}

object RemoteAttachmentsService {

  type GetProviderPrefix = String => Option[String]

}

class RemoteAttachmentsService(getProviderPrefix: GetProviderPrefix) extends Logging {

  def find(
            remoteProvider: UniqueNodeIdentifier,
            guid: Guid,
            name: String): Option[EncryptedAttachment] = Try[EncryptedAttachment] {

    val prefix = getProviderPrefix(remoteProvider).getOrElse(
      fail(s"Failed to get url for remote provider $remoteProvider, cannot retrieve attachments")
    )

    val url = toUrl(prefix, guid, name)
    url.openConnection() match {
      case conn: HttpURLConnection =>
        conn.getResponseCode match {
          case 200 =>
            toEncryptedAttachment(conn, guid, name)
          case badResponseCode =>
            fail(s"Remote provider $remoteProvider with url ${url} returned bad code $badResponseCode")
        }
      case conn =>
        toEncryptedAttachment(conn, guid, name)
    }

  } match {
    case Failure(e) =>
      log.error(s"Failed to get $name from provider $remoteProvider", e)
      None
    case Success(goodResult) =>
      Some(goodResult)
  }

  private def toEncryptedAttachment(conn: URLConnection, guid: Guid, name: String): EncryptedAttachment = {
    val mime = Option(conn.getHeaderField(osMimeHeader)).getOrElse("")
    val encLen = Try(conn.getHeaderField(osEncLenHeader).toLong).getOrElse(0L)
    val iv = {
      val iVasStr = conn.getHeaderField(osIvHeader)
      CBCEncryption.initVector(iVasStr)
    }

    val in = conn.getInputStream
    EncryptedAttachment(in, guid, name, mime, encLen, iv)
  }

  private def toUrl(prefix: UniqueNodeIdentifier,
                    guid: Guid,
                    name: String): URL = {

    val prefixSlash = if(prefix.endsWith("/")) prefix else s"${prefix}/"
    val encodedName = URLEncoder.encode(name, StandardCharsets.UTF_8.name())
    val encodedGuid = URLEncoder.encode(guid.toString(), StandardCharsets.UTF_8.name())
    val suffix = s"${encodedGuid}/${encodedName}"

    new URL(s"${prefixSlash}${suffix}")

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy