Replace ajax base page with Kotlin version
[Sone.git] / src / main / kotlin / net / pterodactylus / sone / web / ajax / JsonPage.kt
diff --git a/src/main/kotlin/net/pterodactylus/sone/web/ajax/JsonPage.kt b/src/main/kotlin/net/pterodactylus/sone/web/ajax/JsonPage.kt
new file mode 100644 (file)
index 0000000..6ba842f
--- /dev/null
@@ -0,0 +1,64 @@
+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")
+       }
+
+}