🔀 Merge branch 'release/v82'
[Sone.git] / src / main / kotlin / net / pterodactylus / sone / web / ajax / JsonPage.kt
1 package net.pterodactylus.sone.web.ajax
2
3 import com.fasterxml.jackson.databind.ObjectMapper
4 import freenet.clients.http.ToadletContext
5 import net.pterodactylus.sone.utils.parameters
6 import net.pterodactylus.sone.web.SessionProvider
7 import net.pterodactylus.sone.web.WebInterface
8 import net.pterodactylus.sone.web.page.*
9 import net.pterodactylus.util.web.Page
10 import net.pterodactylus.util.web.Response
11 import java.io.ByteArrayOutputStream
12 import java.io.PrintStream
13
14 /**
15  * A JSON page is a specialized [Page] that will always return a JSON
16  * object to the browser, e.g. for use with AJAX or other scripting frameworks.
17  */
18 abstract class JsonPage(protected val webInterface: WebInterface) : Page<FreenetRequest> {
19
20         private val objectMapper = ObjectMapper()
21         private val sessionProvider: SessionProvider = webInterface
22         protected val core = webInterface.core
23
24         override fun getPath() = toadletPath
25         override fun isPrefixPage() = false
26
27         open val needsFormPassword = true
28         open val requiresLogin = true
29
30         protected fun createSuccessJsonObject() = JsonReturnObject(true)
31         protected fun createErrorJsonObject(error: String) =
32                         JsonErrorReturnObject(error)
33
34         protected fun getCurrentSone(toadletContext: ToadletContext) =
35                         sessionProvider.getCurrentSone(toadletContext)
36
37         override fun handleRequest(request: FreenetRequest, response: Response): Response {
38                 if (core.preferences.requireFullAccess && !request.toadletContext.isAllowedFullAccess) {
39                         return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
40                 }
41                 if (needsFormPassword && request.parameters["formPassword"] != webInterface.formPassword) {
42                         return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
43                 }
44                 if (requiresLogin && (sessionProvider.getCurrentSone(request.toadletContext) == null)) {
45                         return response.setStatusCode(403).setStatusText("Forbidden").setContentType("application/json").write(createErrorJsonObject("auth-required").asJsonString())
46                 }
47                 return try {
48                         response.setStatusCode(200).setStatusText("OK").setContentType("application/json").write(createJsonObject(request).asJsonString())
49                 } catch (e: Exception) {
50                         response.setStatusCode(500).setStatusText(e.message).setContentType("text/plain").write(e.dumpStackTrace())
51                 }
52         }
53
54         abstract fun createJsonObject(request: FreenetRequest): JsonReturnObject
55
56         private fun JsonReturnObject.asJsonString(): String = objectMapper.writeValueAsString(this)
57
58         private fun Throwable.dumpStackTrace(): String = ByteArrayOutputStream().use {
59                 PrintStream(it, true, "UTF-8").use {
60                         this.printStackTrace(it)
61                 }
62                 it.toString("UTF-8")
63         }
64
65 }