/
SipiResponderADM.scala
143 lines (123 loc) · 7.16 KB
/
SipiResponderADM.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
* SPDX-License-Identifier: Apache-2.0
*/
package org.knora.webapi.responders.admin
import akka.http.scaladsl.util.FastFuture
import akka.pattern._
import scala.concurrent.Future
import dsp.errors.BadRequestException
import dsp.errors.InconsistentRepositoryDataException
import dsp.errors.NotFoundException
import org.knora.webapi.messages.SmartIri
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectIdentifierADM._
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectRestrictedViewSettingsADM
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectRestrictedViewSettingsGetADM
import org.knora.webapi.messages.admin.responder.sipimessages.SipiFileInfoGetRequestADM
import org.knora.webapi.messages.admin.responder.sipimessages.SipiFileInfoGetResponseADM
import org.knora.webapi.messages.admin.responder.sipimessages.SipiResponderRequestADM
import org.knora.webapi.messages.store.triplestoremessages.IriSubjectV2
import org.knora.webapi.messages.store.triplestoremessages.LiteralV2
import org.knora.webapi.messages.store.triplestoremessages.SparqlExtendedConstructRequest
import org.knora.webapi.messages.store.triplestoremessages.SparqlExtendedConstructResponse
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.messages.util.PermissionUtilADM
import org.knora.webapi.messages.util.PermissionUtilADM.EntityPermission
import org.knora.webapi.messages.util.ResponderData
import org.knora.webapi.responders.Responder
/**
* Responds to requests for information about binary representations of resources, and returns responses in Knora API
* ADM format.
*/
class SipiResponderADM(responderData: ResponderData) extends Responder(responderData.actorDeps) {
/**
* Receives a message of type [[SipiResponderRequestADM]], and returns an appropriate response message, or
* [[Status.Failure]]. If a serious error occurs (i.e. an error that isn't the client's fault), this
* method first returns `Failure` to the sender, then throws an exception.
*/
def receive(msg: SipiResponderRequestADM) = msg match {
case sipiFileInfoGetRequestADM: SipiFileInfoGetRequestADM => getFileInfoForSipiADM(sipiFileInfoGetRequestADM)
case other => handleUnexpectedMessage(other, log, this.getClass.getName)
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Methods for generating complete responses.
/**
* Returns a [[SipiFileInfoGetResponseADM]] containing the permissions and path for a file.
*
* @param request the request.
* @return a [[SipiFileInfoGetResponseADM]].
*/
private def getFileInfoForSipiADM(request: SipiFileInfoGetRequestADM): Future[SipiFileInfoGetResponseADM] = {
log.debug(
s"SipiResponderADM - getFileInfoForSipiADM: projectID: ${request.projectID}, filename: ${request.filename}, user: ${request.requestingUser.username}"
)
for {
sparqlQuery <- Future(
org.knora.webapi.messages.twirl.queries.sparql.admin.txt
.getFileValue(
filename = request.filename
)
.toString()
)
queryResponse: SparqlExtendedConstructResponse <- appActor
.ask(
SparqlExtendedConstructRequest(
sparql = sparqlQuery
)
)
.mapTo[SparqlExtendedConstructResponse]
_ = if (queryResponse.statements.isEmpty)
throw NotFoundException(s"No file value was found for filename ${request.filename}")
_ = if (queryResponse.statements.size > 1)
throw InconsistentRepositoryDataException(
s"Filename ${request.filename} is used in more than one file value"
)
fileValueIriSubject: IriSubjectV2 = queryResponse.statements.keys.head match {
case iriSubject: IriSubjectV2 => iriSubject
case _ =>
throw InconsistentRepositoryDataException(
s"The subject of the file value with filename ${request.filename} is not an IRI"
)
}
assertions: Seq[(String, String)] = queryResponse.statements(fileValueIriSubject).toSeq.flatMap {
case (predicate: SmartIri, values: Seq[LiteralV2]) =>
values.map { value =>
predicate.toString -> value.toString
}
}
maybeEntityPermission: Option[EntityPermission] = PermissionUtilADM.getUserPermissionFromAssertionsADM(
entityIri = fileValueIriSubject.toString,
assertions = assertions,
requestingUser = request.requestingUser
)
_ =
log.debug(
s"SipiResponderADM - getFileInfoForSipiADM - maybePermissionCode: $maybeEntityPermission, requestingUser: ${request.requestingUser.username}"
)
permissionCode: Int = maybeEntityPermission
.map(_.toInt)
.getOrElse(0) // Sipi expects a permission code from 0 to 8
response <- permissionCode match {
case 1 =>
for {
maybeRVSettings <-
appActor
.ask(
ProjectRestrictedViewSettingsGetADM(
identifier = ShortcodeIdentifier
.fromString(request.projectID)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage)),
requestingUser = KnoraSystemInstances.Users.SystemUser
)
)
.mapTo[Option[ProjectRestrictedViewSettingsADM]]
} yield SipiFileInfoGetResponseADM(permissionCode = permissionCode, maybeRVSettings)
case _ =>
FastFuture.successful(
SipiFileInfoGetResponseADM(permissionCode = permissionCode, restrictedViewSettings = None)
)
}
_ = log.info(s"filename ${request.filename}, permission code: $permissionCode")
} yield response
}
}