Revision 99eefffc src/main/scala/gr/grnet/aquarium/actor/service/rest/RESTActor.scala
b/src/main/scala/gr/grnet/aquarium/actor/service/rest/RESTActor.scala | ||
---|---|---|
40 | 40 |
import cc.spray.can.HttpMethods.GET |
41 | 41 |
import cc.spray.can._ |
42 | 42 |
import gr.grnet.aquarium.util.Loggable |
43 |
import gr.grnet.aquarium.util.shortInfoOf |
|
43 | 44 |
import akka.actor.Actor |
44 | 45 |
import gr.grnet.aquarium.actor.{RESTRole, RoleableActor, RouterRole} |
45 | 46 |
import RESTPaths._ |
... | ... | |
50 | 51 |
import gr.grnet.aquarium.{ResourceLocator, Aquarium} |
51 | 52 |
import com.ckkloverdos.resource.StreamResource |
52 | 53 |
import com.ckkloverdos.maybe.{Failed, NoVal, Just} |
54 |
import java.net.InetAddress |
|
53 | 55 |
|
54 | 56 |
/** |
55 | 57 |
* Spray-based REST service. This is the outer-world's interface to Aquarium functionality. |
... | ... | |
72 | 74 |
} |
73 | 75 |
|
74 | 76 |
private def resourceInfoResponse( |
77 |
uri: String, |
|
75 | 78 |
responder: RequestResponder, |
76 | 79 |
resource: StreamResource, |
77 | 80 |
contentType: String |
... | ... | |
82 | 85 |
|
83 | 86 |
res match { |
84 | 87 |
case Failed(e) ⇒ |
85 |
logger.error("While serving %s".format(resource), e) |
|
88 |
logger.error("While serving %s".format(uri), e) |
|
89 |
responder.complete(stringResponse(501, "Internal Server Error: %s".format(shortInfoOf(e)), "text/plain")) |
|
86 | 90 |
|
87 | 91 |
case _ ⇒ |
88 | 92 |
|
89 | 93 |
} |
90 | 94 |
} |
91 | 95 |
|
96 |
def withAdminCookie( |
|
97 |
uri: String, |
|
98 |
responder: RequestResponder, |
|
99 |
headers: List[HttpHeader], |
|
100 |
remoteAddress: InetAddress |
|
101 |
)( f: RequestResponder ⇒ Unit): Unit = { |
|
102 |
|
|
103 |
aquarium.adminCookie match { |
|
104 |
case Just(adminCookie) ⇒ |
|
105 |
headers.find(_.name.toLowerCase == Aquarium.HTTP.RESTAdminHeaderNameLowerCase) match { |
|
106 |
case Some(cookieHeader) if(cookieHeader.value == adminCookie) ⇒ |
|
107 |
try f(responder) |
|
108 |
catch { |
|
109 |
case e: Throwable ⇒ |
|
110 |
logger.error("While serving %s".format(uri), e) |
|
111 |
responder.complete(stringResponse(501, "Internal Server Error: %s".format(shortInfoOf(e)), "text/plain")) |
|
112 |
} |
|
113 |
|
|
114 |
case Some(cookieHeader) ⇒ |
|
115 |
logger.warn("Admin request %s with bad cookie '%s' from %s".format(uri, cookieHeader.value, remoteAddress)) |
|
116 |
responder.complete(stringResponse(401, "Unauthorized!", "text/plain")) |
|
117 |
|
|
118 |
case None ⇒ |
|
119 |
logger.warn("Admin request %s with no cookie from %s".format(uri, remoteAddress)) |
|
120 |
responder.complete(stringResponse(401, "Unauthorized!", "text/plain")) |
|
121 |
} |
|
122 |
|
|
123 |
case NoVal ⇒ |
|
124 |
responder.complete(stringResponse(403, "Forbidden!", "text/plain")) |
|
125 |
} |
|
126 |
} |
|
127 |
|
|
92 | 128 |
private def stringResponse200(stringBody: String, contentType: String = "application/json"): HttpResponse = { |
93 | 129 |
stringResponse(200, stringBody, contentType) |
94 | 130 |
} |
... | ... | |
130 | 166 |
callRouter(GetUserStateRequest(userId, millis), responder) |
131 | 167 |
|
132 | 168 |
case AdminPingAll() ⇒ |
133 |
// /admin/ping/all/? |
|
134 |
aquarium.adminCookie match { |
|
135 |
case Just(adminCookie) ⇒ |
|
136 |
headers.find(_.name.toLowerCase == Aquarium.HTTP.RESTAdminHeaderNameLowerCase) match { |
|
137 |
case Some(cookieHeader) if(cookieHeader.value == adminCookie) ⇒ |
|
138 |
callRouter(PingAllRequest(), responder) |
|
139 |
|
|
140 |
case Some(cookieHeader) ⇒ |
|
141 |
logger.warn("Admin request with bad cookie '{}' from {}", cookieHeader.value, remoteAddress) |
|
142 |
responder.complete(stringResponse(401, "Unauthorized!", "text/plain")) |
|
143 |
|
|
144 |
case None ⇒ |
|
145 |
logger.warn("Admin request with no cookie") |
|
146 |
responder.complete(stringResponse(401, "Unauthorized!", "text/plain")) |
|
147 |
} |
|
148 |
|
|
149 |
case NoVal ⇒ |
|
150 |
responder.complete(stringResponse(403, "Forbidden!", "text/plain")) |
|
169 |
withAdminCookie(uri, responder, headers, remoteAddress) { responder ⇒ |
|
170 |
callRouter(PingAllRequest(), responder) |
|
151 | 171 |
} |
152 | 172 |
|
153 | 173 |
case ResourcesAquariumProperties() ⇒ |
154 |
resourceInfoResponse(responder, ResourceLocator.Resources.AquariumPropertiesResource, "text/plain") |
|
174 |
withAdminCookie(uri, responder, headers, remoteAddress) { responder ⇒ |
|
175 |
resourceInfoResponse(uri, responder, ResourceLocator.Resources.AquariumPropertiesResource, "text/plain") |
|
176 |
} |
|
155 | 177 |
|
156 | 178 |
case ResourcesLogbackXML() ⇒ |
157 |
resourceInfoResponse(responder, ResourceLocator.Resources.LogbackXMLResource, "text/plain") |
|
179 |
withAdminCookie(uri, responder, headers, remoteAddress) { responder ⇒ |
|
180 |
resourceInfoResponse(uri, responder, ResourceLocator.Resources.LogbackXMLResource, "text/plain") |
|
181 |
} |
|
158 | 182 |
|
159 | 183 |
case ResourcesPolicyYAML() ⇒ |
160 |
resourceInfoResponse(responder, ResourceLocator.Resources.PolicyYAMLResource, "text/plain") |
|
184 |
withAdminCookie(uri, responder, headers, remoteAddress) { responder ⇒ |
|
185 |
resourceInfoResponse(uri, responder, ResourceLocator.Resources.PolicyYAMLResource, "text/plain") |
|
186 |
} |
|
161 | 187 |
|
162 | 188 |
case _ ⇒ |
163 | 189 |
responder.complete(stringResponse(404, "Unknown resource!", "text/plain")) |
Also available in: Unified diff