annotation class TemplatePath(val value: String)
val Page<*>.templatePath get() = javaClass.getAnnotation(TemplatePath::class.java)?.value
+
+annotation class ToadletPath(val value: String)
+
+val Page<*>.toadletPath get() = javaClass.getAnnotation(ToadletPath::class.java)?.value
* fit into Freenet’s web interface.
*/
open class FreenetTemplatePage(
- private val path: String,
+ path: String,
private val templateRenderer: TemplateRenderer,
loaders: Loaders,
private val invalidFormPasswordRedirectTarget: String
open val shortcutIcon: String? get() = null
open val isFullAccessOnly get() = false
- override fun getPath() = path
+ override fun getPath() = toadletPath
open fun getPageTitle(request: FreenetRequest) = ""
*/
@MenuName("About")
@TemplatePath("/templates/about.html")
+@ToadletPath("about.html")
class AboutPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer,
private val pluginVersion: PluginVersion,
private val pluginYear: PluginYear,
/**
* Page that lets the user bookmark a post.
*/
+@ToadletPath("bookmark.html")
class BookmarkPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer)
: SoneTemplatePage("bookmark.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.Bookmark.Title") {
*/
@MenuName("Bookmarks")
@TemplatePath("/templates/bookmarks.html")
+@ToadletPath("bookmarks.html")
class BookmarksPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("bookmarks.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.Bookmarks.Title") {
* Page that lets the user create a new album.
*/
@TemplatePath("/templates/createAlbum.html")
+@ToadletPath("createAlbum.html")
class CreateAlbumPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("createAlbum.html", "Page.CreateAlbum.Title", webInterface, loaders, templateRenderer) {
* This page lets the user create a new [Post].
*/
@TemplatePath("/templates/createPost.html")
+@ToadletPath("createPost.html")
class CreatePostPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("createPost.html", "Page.CreatePost.Title", webInterface, loaders, templateRenderer) {
* This page lets the user post a reply to a post.
*/
@TemplatePath("/templates/createReply.html")
+@ToadletPath("createReply.html")
class CreateReplyPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("createReply.html", "Page.CreateReply.Title", webInterface, loaders, templateRenderer) {
*/
@MenuName("CreateSone")
@TemplatePath("/templates/createSone.html")
+@ToadletPath("createSone.html")
class CreateSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("createSone.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.CreateSone.Title") {
* Page that lets the user delete an {@link Album}.
*/
@TemplatePath("/templates/deleteAlbum.html")
+@ToadletPath("deleteAlbum.html")
class DeleteAlbumPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("deleteAlbum.html", "Page.DeleteAlbum.Title", webInterface, loaders, templateRenderer) {
* Page that lets the user delete an {@link Image}.
*/
@TemplatePath("/templates/deleteImage.html")
+@ToadletPath("deleteImage.html")
class DeleteImagePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("deleteImage.html", "Page.DeleteImage.Title", webInterface, loaders, templateRenderer) {
* Lets the user delete a post they made.
*/
@TemplatePath("/templates/deletePost.html")
+@ToadletPath("deletePost.html")
class DeletePostPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("deletePost.html", "Page.DeletePost.Title", webInterface, loaders, templateRenderer) {
* Page that lets the user confirm the deletion of a profile field.
*/
@TemplatePath("/templates/deleteProfileField.html")
+@ToadletPath("deleteProfileField.html")
class DeleteProfileFieldPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("deleteProfileField.html", "Page.DeleteProfileField.Title", webInterface, loaders, templateRenderer) {
* This page lets the user delete a reply.
*/
@TemplatePath("/templates/deleteReply.html")
+@ToadletPath("deleteReply.html")
class DeleteReplyPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("deleteReply.html", "Page.DeleteReply.Title", webInterface, loaders, templateRenderer) {
*/
@MenuName("DeleteSone")
@TemplatePath("/templates/deleteSone.html")
+@ToadletPath("deleteSone.html")
class DeleteSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("deleteSone.html", "Page.DeleteSone.Title", webInterface, loaders, templateRenderer) {
/**
* Page that lets the user dismiss a notification.
*/
+@ToadletPath("dismissNotification.html")
class DismissNotificationPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("dismissNotification.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.DismissNotification.Title") {
*
* @see net.pterodactylus.sone.core.Core#distrustSone(Sone, Sone)
*/
+@ToadletPath("distrust.html")
class DistrustPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("distrust.html", "Page.Distrust.Title", webInterface, loaders, templateRenderer) {
/**
* Page that lets the user edit the name and description of an album.
*/
+@ToadletPath("editAlbum.html")
class EditAlbumPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("editAlbum.html", "Page.EditAlbum.Title", webInterface, loaders, templateRenderer) {
/**
* Page that lets the user edit title and description of an {@link Image}.
*/
+@ToadletPath("editImage.html")
class EditImagePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("editImage.html", "Page.EditImage.Title", webInterface, loaders, templateRenderer) {
* Page that lets the user edit the name of a profile field.
*/
@TemplatePath("/templates/editProfileField.html")
+@ToadletPath("editProfileField.html")
class EditProfileFieldPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("editProfileField.html", "Page.EditProfileField.Title", webInterface, loaders, templateRenderer) {
*/
@MenuName("EditProfile")
@TemplatePath("/templates/editProfile.html")
+@ToadletPath("editProfile.html")
class EditProfilePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("editProfile.html", "Page.EditProfile.Title", webInterface, loaders, templateRenderer) {
import net.pterodactylus.sone.web.page.*
@TemplatePath("/templates/invalid.html")
+@ToadletPath("invalid.html")
class InvalidPage(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) : SoneTemplatePage("invalid.html", webInterface, loaders, templateRenderer, "Page.Invalid.Title")
@TemplatePath("/templates/noPermission.html")
+@ToadletPath("noPermission.html")
class NoPermissionPage(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) : SoneTemplatePage("noPermission.html", webInterface, loaders, templateRenderer, "Page.NoPermission.Title")
@TemplatePath("/templates/emptyImageTitle.html")
+@ToadletPath("emptyImageTitle.html")
class EmptyImageTitlePage(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) : SoneTemplatePage("emptyImageTitle.html", webInterface, loaders, templateRenderer, "Page.EmptyImageTitle.Title")
@TemplatePath("/templates/emptyAlbumTitle.html")
+@ToadletPath("emptyAlbumTitle.html")
class EmptyAlbumTitlePage(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) : SoneTemplatePage("emptyAlbumTitle.html", webInterface, loaders, templateRenderer, "Page.EmptyAlbumTitle.Title")
/**
* This page lets the user follow another Sone.
*/
+@ToadletPath("followSone.html")
class FollowSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("followSone.html", "Page.FollowSone.Title", webInterface, loaders, templateRenderer) {
*/
@MenuName("ImageBrowser")
@TemplatePath("/templates/imageBrowser.html")
+@ToadletPath("imageBrowser.html")
class ImageBrowserPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("imageBrowser.html", "Page.ImageBrowser.Title", webInterface, loaders, templateRenderer) {
*/
@MenuName("Index")
@TemplatePath("/templates/index.html")
+@ToadletPath("index.html")
class IndexPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer, private val postVisibilityFilter: PostVisibilityFilter) :
LoggedInPage("index.html", "Page.Index.Title", webInterface, loaders, templateRenderer) {
*/
@MenuName("KnownSones")
@TemplatePath("/templates/knownSones.html")
+@ToadletPath("knownSones.html")
class KnownSonesPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("knownSones.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.KnownSones.Title") {
/**
* Page that lets the user like [net.pterodactylus.sone.data.Post]s and [net.pterodactylus.sone.data.Reply]s.
*/
+@ToadletPath("like.html")
class LikePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("like.html", "Page.Like.Title", webInterface, loaders, templateRenderer) {
/**
* This page lets the user lock a [net.pterodactylus.sone.data.Sone] to prevent it from being inserted.
*/
+@ToadletPath("lockSone.html")
class LockSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("lockSone.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.LockSone.Title") {
*/
@MenuName("Login")
@TemplatePath("/templates/login.html")
+@ToadletPath("login.html")
class LoginPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("login.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.Login.Title") {
* Logs a user out.
*/
@MenuName("Logout")
+@ToadletPath("logout.html")
class LogoutPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("logout.html", "Page.Logout.Title", webInterface, loaders, templateRenderer) {
* Page that lets the user mark a number of [net.pterodactylus.sone.data.Sone]s, [Post]s, or
* [Replie][net.pterodactylus.sone.data.Reply]s as known.
*/
+@ToadletPath("markAsKnown.html")
class MarkAsKnownPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("markAsKnown.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.MarkAsKnown.Title") {
*/
@MenuName("New")
@TemplatePath("/templates/new.html")
+@ToadletPath("new.html")
class NewPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("new.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.New.Title") {
*/
@MenuName("Options")
@TemplatePath("/templates/options.html")
+@ToadletPath("options.html")
class OptionsPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("options.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.Options.Title") {
*/
@MenuName("Rescue")
@TemplatePath("/templates/rescue.html")
+@ToadletPath("rescue.html")
class RescuePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("rescue.html", "Page.Rescue.Title", webInterface, loaders, templateRenderer) {
* words.
*/
@TemplatePath("/templates/search.html")
+@ToadletPath("search.html")
class SearchPage(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer, ticker: Ticker = Ticker.systemTicker()) :
SoneTemplatePage("search.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.Search.Title") {
* Page that lets the user trust another Sone. This will assign a configurable
* amount of trust to an identity.
*/
+@ToadletPath("trust.html")
class TrustPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("trust.html", "Page.Trust.Title", webInterface, loaders, templateRenderer) {
/**
* Page that lets the user unbookmark a post.
*/
+@ToadletPath("unbookmark.html")
class UnbookmarkPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("unbookmark.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.Unbookmark.Title") {
/**
* This page lets the user unfollow another Sone.
*/
+@ToadletPath("unfollowSone.html")
class UnfollowSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("unfollowSone.html", "Page.UnfollowSone.Title", webInterface, loaders, templateRenderer) {
/**
* Page that lets the user unlike a [net.pterodactylus.sone.data.Post] or [net.pterodactylus.sone.data.Reply].
*/
+@ToadletPath("unlike.html")
class UnlikePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("unlike.html", "Page.Unlike.Title", webInterface, loaders, templateRenderer) {
/**
* This page lets the user unlock a [net.pterodactylus.sone.data.Sone] to allow its insertion.
*/
+@ToadletPath("unlockSone.html")
class UnlockSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("unlockSone.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.UnlockSone.Title") {
* Page that lets the user untrust another Sone. This will remove all trust
* assignments for an identity.
*/
+@ToadletPath("untrust.html")
class UntrustPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("untrust.html", "Page.Untrust.Title", webInterface, loaders, templateRenderer) {
* Page implementation that lets the user upload an image.
*/
@TemplatePath("/templates/invalid.html")
+@ToadletPath("uploadImage.html")
class UploadImagePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
LoggedInPage("uploadImage.html", "Page.UploadImage.Title", webInterface, loaders, templateRenderer) {
* This page lets the user view a post and all its replies.
*/
@TemplatePath("/templates/viewPost.html")
+@ToadletPath("viewPost.html")
class ViewPostPage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("viewPost.html", webInterface, loaders, templateRenderer, pageTitleKey = "Page.ViewPost.Title") {
* Lets the user browser another Sone.
*/
@TemplatePath("/templates/viewSone.html")
+@ToadletPath("viewSone.html")
class ViewSonePage @Inject constructor(webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer) :
SoneTemplatePage("viewSone.html", webInterface, loaders, templateRenderer) {
private val templateRenderer = deepMock<TemplateRenderer>()
private val loaders = mock<Loaders>()
private val template = mock<Template>()
- private val page = FreenetTemplatePage("/test/path", templateRenderer, loaders, "invalid-form-password")
+ private val page = TestPage(templateRenderer, loaders)
@Test
fun `path is exposed correctly`() {
@Test
fun `isEnabled() returns false if full access only is true`() {
- val page = object : FreenetTemplatePage("/test/path", templateRenderer, loaders, "invalid-form-password") {
+ val page = object : TestPage(templateRenderer, loaders) {
override val isFullAccessOnly = true
}
assertThat(page.isEnabled(mock()), equalTo(false))
@Test
fun `page with redirect target throws redirect exception on handleRequest`() {
- val page = object : FreenetTemplatePage("/test/path", templateRenderer, loaders, "invalid-form-password") {
+ val page = object : TestPage(templateRenderer, loaders) {
override fun getRedirectTarget(request: FreenetRequest) = "foo"
}
val request = mock<FreenetRequest>()
@Test
fun `page with full access only returns unauthorized on handleRequest with non-full access request`() {
- val page = object : FreenetTemplatePage("/test/path", templateRenderer, loaders, "invalid-form-password") {
+ val page = object : TestPage(templateRenderer, loaders) {
override val isFullAccessOnly = true
}
val request = deepMock<FreenetRequest>()
@Test
fun `template from annotation is loaded`() {
- val template = deepMock<Template>()
- whenever(loaders.loadTemplate("template-path")).thenReturn(template)
- TestPage(templateRenderer, loaders)
verify(loaders).loadTemplate("template-path")
}
@TemplatePath("template-path")
- private class TestPage(templateRenderer: TemplateRenderer, loaders: Loaders) : FreenetTemplatePage("/", templateRenderer, loaders, "") {
- override fun getPath() = ""
- override fun isPrefixPage() = false
- override fun handleRequest(request: FreenetRequest, response: Response) = response
- }
+ @ToadletPath("/test/path")
+ private open class TestPage(templateRenderer: TemplateRenderer, loaders: Loaders) : FreenetTemplatePage("/", templateRenderer, loaders, "invalid-form-password")
}