@@ -3,129 +3,95 @@ package app.softnetwork.resource.service
33import akka .http .scaladsl .server .Route
44import akka .stream .scaladsl .{FileIO , Source }
55import akka .util .ByteString
6- import app .softnetwork .api .server .{ ApiEndpoint , ApiErrors }
6+ import app .softnetwork .api .server .ApiErrors
77import app .softnetwork .resource .config .ResourceSettings
88import app .softnetwork .resource .handlers .GenericResourceHandler
99import app .softnetwork .resource .message .ResourceMessages ._
1010import app .softnetwork .resource .spi .{ResourceProvider , SimpleResource }
11- import app .softnetwork .session .service .SessionEndpoints
12- import com .softwaremill .session .{
13- GetSessionTransport ,
14- SetSessionTransport ,
15- TapirCsrfCheckMode ,
16- TapirSessionContinuity
17- }
11+ import app .softnetwork .session .service .ServiceWithSessionEndpoints
1812import org .softnetwork .session .model .Session
1913import sttp .capabilities .akka .AkkaStreams
2014import sttp .model .headers .CookieValueWithMeta
2115import sttp .model .{Method , Part , StatusCode }
22- import sttp .monad .FutureMonad
2316import sttp .tapir ._
24- import sttp .tapir .generic .auto ._
2517import sttp .tapir .json .json4s .jsonBody
26- import sttp .tapir .server .{PartialServerEndpoint , ServerEndpoint }
18+ import sttp .tapir .server .{PartialServerEndpointWithSecurityOutput , ServerEndpoint }
2719
2820import scala .concurrent .Future
2921
30- trait ResourceServiceEndpoints extends LoadResourceService with ApiEndpoint {
22+ trait ResourceServiceEndpoints
23+ extends LoadResourceService
24+ with ServiceWithSessionEndpoints [ResourceCommand , ResourceResult ] {
3125 _ : GenericResourceHandler with ResourceProvider =>
3226
3327 import app .softnetwork .serialization ._
3428
35- def sessionEndpoints : SessionEndpoints
36-
37- def sc : TapirSessionContinuity [Session ] = sessionEndpoints.sc
38-
39- def st : SetSessionTransport = sessionEndpoints.st
40-
41- def gt : GetSessionTransport = sessionEndpoints.gt
42-
43- def checkMode : TapirCsrfCheckMode [Session ] = sessionEndpoints.checkMode
44-
4529 def error (e : ResourceError ): ApiErrors .ErrorInfo =
4630 e match {
4731 case ResourceNotFound => ApiErrors .NotFound (ResourceNotFound )
4832 case _ => ApiErrors .BadRequest (e.message)
4933 }
5034
51- def rootEndpoint : PartialServerEndpoint [
35+ def secureEndpoint : PartialServerEndpointWithSecurityOutput [
5236 (Seq [Option [String ]], Option [String ], Method , Option [String ]),
53- (( Seq [ Option [ String ]], Option [ CookieValueWithMeta ]), Session ) ,
37+ Session ,
5438 Unit ,
55- ApiErrors . ErrorInfo ,
39+ Any ,
5640 (Seq [Option [String ]], Option [CookieValueWithMeta ]),
41+ Unit ,
5742 Any ,
5843 Future
59- ] = {
60- val partial =
61- sessionEndpoints.antiCsrfWithRequiredSession(sc, gt, checkMode)
62- partial.endpoint
44+ ] =
45+ ApiErrors
46+ .withApiErrorVariants(
47+ antiCsrfWithRequiredSession(sc, gt, checkMode)
48+ )
6349 .in(ResourceSettings .ResourcePath )
64- .out(partial.securityOutput)
65- .errorOut(errors)
66- .serverSecurityLogic { inputs =>
67- partial.securityLogic(new FutureMonad ())(inputs).map {
68- case Left (_) => Left (ApiErrors .Unauthorized (" Unauthorized" ))
69- case Right (r) => Right ((r._1, r._2))
70- }
71- }
72- }
7350
7451 val library : ServerEndpoint [Any with AkkaStreams , Future ] =
75- rootEndpoint .get
52+ secureEndpoint .get
7653 .in(" library" )
7754 .in(paths)
7855 .out(jsonBody[List [SimpleResource ]])
79- .serverLogicSuccess(principal =>
80- segments =>
81- Future .successful(
82- (principal._1._1, principal._1._2, listResources(segments.mkString(" /" )))
83- )
84- )
56+ .serverLogicSuccess(_ => segments => Future .successful(listResources(segments.mkString(" /" ))))
8557
86- def loadResourceBusinessLogic (
87- principal : ((Seq [Option [String ]], Option [CookieValueWithMeta ]), Session )
88- ): List [String ] => Either [
58+ def loadResourceBusinessLogic (segments : List [String ]): Either [
8959 ApiErrors .ErrorInfo ,
90- ( Seq [ Option [ String ]], Option [ CookieValueWithMeta ], Source [ByteString , Any ])
60+ Source [ByteString , Any ]
9161 ] =
92- segments =>
93- loadResource(segments) match {
94- case Some ((path, _)) => Right ((principal._1._1, principal._1._2, FileIO .fromPath(path)))
95- case _ => Left (error(ResourceNotFound ))
96- }
62+ loadResource(segments) match {
63+ case Some ((path, _)) => Right (FileIO .fromPath(path))
64+ case _ => Left (error(ResourceNotFound ))
65+ }
9766
9867 val getResource : ServerEndpoint [Any with AkkaStreams , Future ] =
99- rootEndpoint .get
68+ secureEndpoint .get
10069 .in(paths)
10170 .out(streamBinaryBody(AkkaStreams )(CodecFormat .OctetStream ()))
102- .serverLogic(principal =>
103- segments => Future .successful(loadResourceBusinessLogic(principal)(segments))
104- )
71+ .serverLogic(_ => segments => Future .successful(loadResourceBusinessLogic(segments)))
10572
10673 val getImage : ServerEndpoint [Any with AkkaStreams , Future ] =
107- rootEndpoint .get
74+ secureEndpoint .get
10875 .in(" images" )
10976 .in(paths)
11077 .out(
11178 streamBinaryBody(AkkaStreams )(CodecFormat .OctetStream ())
11279 )
113- .serverLogic(principal =>
114- segments => Future .successful(loadResourceBusinessLogic(principal)(segments))
115- )
80+ .serverLogic(_ => segments => Future .successful(loadResourceBusinessLogic(segments)))
11681
11782 def uploadResource [T <: Upload ](implicit
11883 multipartCodec : MultipartCodec [T ]
119- ): PartialServerEndpoint [
84+ ): PartialServerEndpointWithSecurityOutput [
12085 (Seq [Option [String ]], Option [String ], Method , Option [String ]),
121- (( Seq [ Option [ String ]], Option [ CookieValueWithMeta ]), Session ) ,
86+ Session ,
12287 (List [String ], T ),
123- ApiErrors .ErrorInfo ,
124- (Seq [Option [String ]], Option [CookieValueWithMeta ], ResourceResult ),
88+ Any ,
89+ (Seq [Option [String ]], Option [CookieValueWithMeta ]),
90+ ResourceResult ,
12591 Any ,
12692 Future
12793 ] =
128- rootEndpoint
94+ secureEndpoint
12995 .in(paths.description(" URI of the resource" ))
13096 .in(multipartBody[T ].description(" Multipart file to upload" ))
13197 .out(
@@ -146,10 +112,10 @@ trait ResourceServiceEndpoints extends LoadResourceService with ApiEndpoint {
146112 ): ServerEndpoint [Any with AkkaStreams , Future ] =
147113 uploadResource[T ].post
148114 .description(" Add a resource" )
149- .serverLogic(principal => { case (segments, upload) =>
150- uploadResource(principal._2, segments, upload.bytes, update = false ) map {
115+ .serverLogic(session => { case (segments, upload) =>
116+ uploadResource(session, segments, upload.bytes, update = false ) map {
117+ case Right (r) => Right (r)
151118 case Left (l) => Left (error(l))
152- case Right (r) => Right ((principal._1._1, principal._1._2, r))
153119 }
154120 })
155121
@@ -158,25 +124,26 @@ trait ResourceServiceEndpoints extends LoadResourceService with ApiEndpoint {
158124 ): ServerEndpoint [Any with AkkaStreams , Future ] =
159125 uploadResource[T ].put
160126 .description(" Update the resource" )
161- .serverLogic(principal => { case (segments, upload) =>
162- uploadResource(principal._2, segments, upload.bytes, update = true ) map {
127+ .serverLogic(session => { case (segments, upload) =>
128+ uploadResource(session, segments, upload.bytes, update = true ) map {
129+ case Right (r) => Right (r)
163130 case Left (l) => Left (error(l))
164- case Right (r) => Right ((principal._1._1, principal._1._2, r))
165131 }
166132 })
167133
168134 def uploadImage [T <: Upload ](implicit
169135 multipartCodec : MultipartCodec [T ]
170- ): PartialServerEndpoint [
136+ ): PartialServerEndpointWithSecurityOutput [
171137 (Seq [Option [String ]], Option [String ], Method , Option [String ]),
172- (( Seq [ Option [ String ]], Option [ CookieValueWithMeta ]), Session ) ,
138+ Session ,
173139 (List [String ], T ),
174- ApiErrors .ErrorInfo ,
175- (Seq [Option [String ]], Option [CookieValueWithMeta ], ResourceResult ),
140+ Any ,
141+ (Seq [Option [String ]], Option [CookieValueWithMeta ]),
142+ ResourceResult ,
176143 Any ,
177144 Future
178145 ] =
179- rootEndpoint
146+ secureEndpoint
180147 .in(" images" )
181148 .in(paths.description(" URI of the image" ))
182149 .in(multipartBody[T ].description(" Multipart image to upload" ))
@@ -198,10 +165,10 @@ trait ResourceServiceEndpoints extends LoadResourceService with ApiEndpoint {
198165 ): ServerEndpoint [Any with AkkaStreams , Future ] =
199166 uploadImage[T ].post
200167 .description(" Add an image" )
201- .serverLogic(principal => { case (segments, upload) =>
202- uploadResource(principal._2, segments, upload.bytes, update = false ) map {
168+ .serverLogic(session => { case (segments, upload) =>
169+ uploadResource(session, segments, upload.bytes, update = false ) map {
170+ case Right (r) => Right (r)
203171 case Left (l) => Left (error(l))
204- case Right (r) => Right ((principal._1._1, principal._1._2, r))
205172 }
206173 })
207174
@@ -210,10 +177,10 @@ trait ResourceServiceEndpoints extends LoadResourceService with ApiEndpoint {
210177 ): ServerEndpoint [Any with AkkaStreams , Future ] =
211178 uploadImage[T ].put
212179 .description(" Update the image" )
213- .serverLogic(principal => { case (segments, upload) =>
214- uploadResource(principal._2, segments, upload.bytes, update = true ) map {
180+ .serverLogic(session => { case (segments, upload) =>
181+ uploadResource(session, segments, upload.bytes, update = true ) map {
182+ case Right (r) => Right (r)
215183 case Left (l) => Left (error(l))
216- case Right (r) => Right ((principal._1._1, principal._1._2, r))
217184 }
218185 })
219186
@@ -229,27 +196,27 @@ trait ResourceServiceEndpoints extends LoadResourceService with ApiEndpoint {
229196 }
230197
231198 val deleteResource : ServerEndpoint [Any with AkkaStreams , Future ] =
232- rootEndpoint
199+ secureEndpoint
233200 .in(paths)
234201 .delete
235- .serverLogic(principal =>
202+ .serverLogic(session =>
236203 segments =>
237- deleteResourceBusinessLogic(principal._2, segments) map {
204+ deleteResourceBusinessLogic(session, segments) map {
205+ case Right (_) => Right (())
238206 case Left (l) => Left (error(l))
239- case Right (_) => Right ((principal._1._1, principal._1._2))
240207 }
241208 )
242209
243210 val deleteImage : ServerEndpoint [Any with AkkaStreams , Future ] =
244- rootEndpoint
211+ secureEndpoint
245212 .in(" images" )
246213 .in(paths)
247214 .delete
248- .serverLogic(principal =>
215+ .serverLogic(session =>
249216 segments =>
250- deleteResourceBusinessLogic(principal._2, segments) map {
217+ deleteResourceBusinessLogic(session, segments) map {
218+ case Right (_) => Right (())
251219 case Left (l) => Left (error(l))
252- case Right (_) => Right ((principal._1._1, principal._1._2))
253220 }
254221 )
255222
0 commit comments