--- /dev/null
+package net.pterodactylus.sone.web.ajax
+
+import com.fasterxml.jackson.databind.ObjectMapper
+import freenet.clients.http.ToadletContext
+import net.pterodactylus.sone.utils.parameters
+import net.pterodactylus.sone.web.SessionProvider
+import net.pterodactylus.sone.web.WebInterface
+import net.pterodactylus.sone.web.page.FreenetRequest
+import net.pterodactylus.util.web.Page
+import net.pterodactylus.util.web.Response
+import java.io.ByteArrayOutputStream
+import java.io.PrintStream
+
+/**
+ * A JSON page is a specialized [Page] that will always return a JSON
+ * object to the browser, e.g. for use with AJAX or other scripting frameworks.
+ */
+abstract class JsonPage(private val path: String, protected val webInterface: WebInterface) : Page<FreenetRequest> {
+
+ private val objectMapper = ObjectMapper()
+ private val sessionProvider: SessionProvider = webInterface
+
+ override fun getPath() = path
+ override fun isPrefixPage() = false
+
+ open fun needsFormPassword() = true
+ open fun requiresLogin() = true
+
+ protected fun createSuccessJsonObject() = JsonReturnObject(true)
+ protected fun createErrorJsonObject(error: String) =
+ JsonErrorReturnObject(error)
+
+ protected fun getCurrentSone(toadletContext: ToadletContext, createSession: Boolean = true) =
+ sessionProvider.getCurrentSone(toadletContext, createSession)
+
+ override fun handleRequest(request: FreenetRequest, response: Response): Response {
+ if (webInterface.core.preferences.isRequireFullAccess && !request.toadletContext.isAllowedFullAccess) {
+ return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
+ }
+ if (needsFormPassword() && request.parameters["formPassword"] != webInterface.formPassword) {
+ return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
+ }
+ if (requiresLogin() && (sessionProvider.getCurrentSone(request.toadletContext, false) == null)) {
+ return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
+ }
+ return try {
+ response.setStatusCode(200).setStatusText("OK").setContentType("application/json").write(createJsonObject(request).asJsonString())
+ } catch (e: Exception) {
+ response.setStatusCode(500).setStatusText(e.message).setContentType("text/plain").write(e.dumpStackTrace())
+ }
+ }
+
+ abstract fun createJsonObject(request: FreenetRequest): JsonReturnObject
+
+ private fun JsonReturnObject.asJsonString(): String = objectMapper.writeValueAsString(this)
+
+ private fun Throwable.dumpStackTrace(): String = ByteArrayOutputStream().use {
+ PrintStream(it, true, "UTF-8").use {
+ this.printStackTrace(it)
+ }
+ it.toString("UTF-8")
+ }
+
+}