mirror of
https://github.com/miniflux/v2.git
synced 2025-08-01 17:38:37 +00:00
Move internal packages to an internal folder
For reference: https://go.dev/doc/go1.4#internalpackages
This commit is contained in:
parent
c234903255
commit
168a870c02
433 changed files with 1121 additions and 1123 deletions
31
internal/ui/form/api_key.go
Normal file
31
internal/ui/form/api_key.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"miniflux.app/v2/internal/errors"
|
||||
)
|
||||
|
||||
// APIKeyForm represents the API Key form.
|
||||
type APIKeyForm struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
// Validate makes sure the form values are valid.
|
||||
func (a APIKeyForm) Validate() error {
|
||||
if a.Description == "" {
|
||||
return errors.NewLocalizedError("error.fields_mandatory")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAPIKeyForm returns a new APIKeyForm.
|
||||
func NewAPIKeyForm(r *http.Request) *APIKeyForm {
|
||||
return &APIKeyForm{
|
||||
Description: r.FormValue("description"),
|
||||
}
|
||||
}
|
33
internal/ui/form/auth.go
Normal file
33
internal/ui/form/auth.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"miniflux.app/v2/internal/errors"
|
||||
)
|
||||
|
||||
// AuthForm represents the authentication form.
|
||||
type AuthForm struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// Validate makes sure the form values are valid.
|
||||
func (a AuthForm) Validate() error {
|
||||
if a.Username == "" || a.Password == "" {
|
||||
return errors.NewLocalizedError("error.fields_mandatory")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAuthForm returns a new AuthForm.
|
||||
func NewAuthForm(r *http.Request) *AuthForm {
|
||||
return &AuthForm{
|
||||
Username: r.FormValue("username"),
|
||||
Password: r.FormValue("password"),
|
||||
}
|
||||
}
|
22
internal/ui/form/category.go
Normal file
22
internal/ui/form/category.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CategoryForm represents a feed form in the UI
|
||||
type CategoryForm struct {
|
||||
Title string
|
||||
HideGlobally string
|
||||
}
|
||||
|
||||
// NewCategoryForm returns a new CategoryForm.
|
||||
func NewCategoryForm(r *http.Request) *CategoryForm {
|
||||
return &CategoryForm{
|
||||
Title: r.FormValue("title"),
|
||||
HideGlobally: r.FormValue("hide_globally"),
|
||||
}
|
||||
}
|
93
internal/ui/form/feed.go
Normal file
93
internal/ui/form/feed.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"miniflux.app/v2/internal/model"
|
||||
)
|
||||
|
||||
// FeedForm represents a feed form in the UI
|
||||
type FeedForm struct {
|
||||
FeedURL string
|
||||
SiteURL string
|
||||
Title string
|
||||
ScraperRules string
|
||||
RewriteRules string
|
||||
BlocklistRules string
|
||||
KeeplistRules string
|
||||
UrlRewriteRules string
|
||||
Crawler bool
|
||||
UserAgent string
|
||||
Cookie string
|
||||
CategoryID int64
|
||||
Username string
|
||||
Password string
|
||||
IgnoreHTTPCache bool
|
||||
AllowSelfSignedCertificates bool
|
||||
FetchViaProxy bool
|
||||
Disabled bool
|
||||
NoMediaPlayer bool
|
||||
HideGlobally bool
|
||||
CategoryHidden bool // Category has "hide_globally"
|
||||
}
|
||||
|
||||
// Merge updates the fields of the given feed.
|
||||
func (f FeedForm) Merge(feed *model.Feed) *model.Feed {
|
||||
feed.Category.ID = f.CategoryID
|
||||
feed.Title = f.Title
|
||||
feed.SiteURL = f.SiteURL
|
||||
feed.FeedURL = f.FeedURL
|
||||
feed.ScraperRules = f.ScraperRules
|
||||
feed.RewriteRules = f.RewriteRules
|
||||
feed.BlocklistRules = f.BlocklistRules
|
||||
feed.KeeplistRules = f.KeeplistRules
|
||||
feed.UrlRewriteRules = f.UrlRewriteRules
|
||||
feed.Crawler = f.Crawler
|
||||
feed.UserAgent = f.UserAgent
|
||||
feed.Cookie = f.Cookie
|
||||
feed.ParsingErrorCount = 0
|
||||
feed.ParsingErrorMsg = ""
|
||||
feed.Username = f.Username
|
||||
feed.Password = f.Password
|
||||
feed.IgnoreHTTPCache = f.IgnoreHTTPCache
|
||||
feed.AllowSelfSignedCertificates = f.AllowSelfSignedCertificates
|
||||
feed.FetchViaProxy = f.FetchViaProxy
|
||||
feed.Disabled = f.Disabled
|
||||
feed.NoMediaPlayer = f.NoMediaPlayer
|
||||
feed.HideGlobally = f.HideGlobally
|
||||
return feed
|
||||
}
|
||||
|
||||
// NewFeedForm parses the HTTP request and returns a FeedForm
|
||||
func NewFeedForm(r *http.Request) *FeedForm {
|
||||
categoryID, err := strconv.Atoi(r.FormValue("category_id"))
|
||||
if err != nil {
|
||||
categoryID = 0
|
||||
}
|
||||
return &FeedForm{
|
||||
FeedURL: r.FormValue("feed_url"),
|
||||
SiteURL: r.FormValue("site_url"),
|
||||
Title: r.FormValue("title"),
|
||||
ScraperRules: r.FormValue("scraper_rules"),
|
||||
UserAgent: r.FormValue("user_agent"),
|
||||
Cookie: r.FormValue("cookie"),
|
||||
RewriteRules: r.FormValue("rewrite_rules"),
|
||||
BlocklistRules: r.FormValue("blocklist_rules"),
|
||||
KeeplistRules: r.FormValue("keeplist_rules"),
|
||||
UrlRewriteRules: r.FormValue("urlrewrite_rules"),
|
||||
Crawler: r.FormValue("crawler") == "1",
|
||||
CategoryID: int64(categoryID),
|
||||
Username: r.FormValue("feed_username"),
|
||||
Password: r.FormValue("feed_password"),
|
||||
IgnoreHTTPCache: r.FormValue("ignore_http_cache") == "1",
|
||||
AllowSelfSignedCertificates: r.FormValue("allow_self_signed_certificates") == "1",
|
||||
FetchViaProxy: r.FormValue("fetch_via_proxy") == "1",
|
||||
Disabled: r.FormValue("disabled") == "1",
|
||||
NoMediaPlayer: r.FormValue("no_media_player") == "1",
|
||||
HideGlobally: r.FormValue("hide_globally") == "1",
|
||||
}
|
||||
}
|
175
internal/ui/form/integration.go
Normal file
175
internal/ui/form/integration.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"miniflux.app/v2/internal/model"
|
||||
)
|
||||
|
||||
// IntegrationForm represents user integration settings form.
|
||||
type IntegrationForm struct {
|
||||
PinboardEnabled bool
|
||||
PinboardToken string
|
||||
PinboardTags string
|
||||
PinboardMarkAsUnread bool
|
||||
InstapaperEnabled bool
|
||||
InstapaperUsername string
|
||||
InstapaperPassword string
|
||||
FeverEnabled bool
|
||||
FeverUsername string
|
||||
FeverPassword string
|
||||
GoogleReaderEnabled bool
|
||||
GoogleReaderUsername string
|
||||
GoogleReaderPassword string
|
||||
WallabagEnabled bool
|
||||
WallabagOnlyURL bool
|
||||
WallabagURL string
|
||||
WallabagClientID string
|
||||
WallabagClientSecret string
|
||||
WallabagUsername string
|
||||
WallabagPassword string
|
||||
NotionEnabled bool
|
||||
NotionPageID string
|
||||
NotionToken string
|
||||
NunuxKeeperEnabled bool
|
||||
NunuxKeeperURL string
|
||||
NunuxKeeperAPIKey string
|
||||
EspialEnabled bool
|
||||
EspialURL string
|
||||
EspialAPIKey string
|
||||
EspialTags string
|
||||
ReadwiseEnabled bool
|
||||
ReadwiseAPIKey string
|
||||
PocketEnabled bool
|
||||
PocketAccessToken string
|
||||
PocketConsumerKey string
|
||||
TelegramBotEnabled bool
|
||||
TelegramBotToken string
|
||||
TelegramBotChatID string
|
||||
LinkdingEnabled bool
|
||||
LinkdingURL string
|
||||
LinkdingAPIKey string
|
||||
LinkdingTags string
|
||||
LinkdingMarkAsUnread bool
|
||||
MatrixBotEnabled bool
|
||||
MatrixBotUser string
|
||||
MatrixBotPassword string
|
||||
MatrixBotURL string
|
||||
MatrixBotChatID string
|
||||
AppriseEnabled bool
|
||||
AppriseURL string
|
||||
AppriseServicesURL string
|
||||
}
|
||||
|
||||
// Merge copy form values to the model.
|
||||
func (i IntegrationForm) Merge(integration *model.Integration) {
|
||||
integration.PinboardEnabled = i.PinboardEnabled
|
||||
integration.PinboardToken = i.PinboardToken
|
||||
integration.PinboardTags = i.PinboardTags
|
||||
integration.PinboardMarkAsUnread = i.PinboardMarkAsUnread
|
||||
integration.InstapaperEnabled = i.InstapaperEnabled
|
||||
integration.InstapaperUsername = i.InstapaperUsername
|
||||
integration.InstapaperPassword = i.InstapaperPassword
|
||||
integration.FeverEnabled = i.FeverEnabled
|
||||
integration.FeverUsername = i.FeverUsername
|
||||
integration.GoogleReaderEnabled = i.GoogleReaderEnabled
|
||||
integration.GoogleReaderUsername = i.GoogleReaderUsername
|
||||
integration.WallabagEnabled = i.WallabagEnabled
|
||||
integration.WallabagOnlyURL = i.WallabagOnlyURL
|
||||
integration.WallabagURL = i.WallabagURL
|
||||
integration.WallabagClientID = i.WallabagClientID
|
||||
integration.WallabagClientSecret = i.WallabagClientSecret
|
||||
integration.WallabagUsername = i.WallabagUsername
|
||||
integration.WallabagPassword = i.WallabagPassword
|
||||
integration.NotionEnabled = i.NotionEnabled
|
||||
integration.NotionPageID = i.NotionPageID
|
||||
integration.NotionToken = i.NotionToken
|
||||
integration.NunuxKeeperEnabled = i.NunuxKeeperEnabled
|
||||
integration.NunuxKeeperURL = i.NunuxKeeperURL
|
||||
integration.NunuxKeeperAPIKey = i.NunuxKeeperAPIKey
|
||||
integration.EspialEnabled = i.EspialEnabled
|
||||
integration.EspialURL = i.EspialURL
|
||||
integration.EspialAPIKey = i.EspialAPIKey
|
||||
integration.EspialTags = i.EspialTags
|
||||
integration.ReadwiseEnabled = i.ReadwiseEnabled
|
||||
integration.ReadwiseAPIKey = i.ReadwiseAPIKey
|
||||
integration.PocketEnabled = i.PocketEnabled
|
||||
integration.PocketAccessToken = i.PocketAccessToken
|
||||
integration.PocketConsumerKey = i.PocketConsumerKey
|
||||
integration.TelegramBotEnabled = i.TelegramBotEnabled
|
||||
integration.TelegramBotToken = i.TelegramBotToken
|
||||
integration.TelegramBotChatID = i.TelegramBotChatID
|
||||
integration.LinkdingEnabled = i.LinkdingEnabled
|
||||
integration.LinkdingURL = i.LinkdingURL
|
||||
integration.LinkdingAPIKey = i.LinkdingAPIKey
|
||||
integration.LinkdingTags = i.LinkdingTags
|
||||
integration.LinkdingMarkAsUnread = i.LinkdingMarkAsUnread
|
||||
integration.MatrixBotEnabled = i.MatrixBotEnabled
|
||||
integration.MatrixBotUser = i.MatrixBotUser
|
||||
integration.MatrixBotPassword = i.MatrixBotPassword
|
||||
integration.MatrixBotURL = i.MatrixBotURL
|
||||
integration.MatrixBotChatID = i.MatrixBotChatID
|
||||
integration.AppriseEnabled = i.AppriseEnabled
|
||||
integration.AppriseServicesURL = i.AppriseServicesURL
|
||||
integration.AppriseURL = i.AppriseURL
|
||||
}
|
||||
|
||||
// NewIntegrationForm returns a new IntegrationForm.
|
||||
func NewIntegrationForm(r *http.Request) *IntegrationForm {
|
||||
return &IntegrationForm{
|
||||
PinboardEnabled: r.FormValue("pinboard_enabled") == "1",
|
||||
PinboardToken: r.FormValue("pinboard_token"),
|
||||
PinboardTags: r.FormValue("pinboard_tags"),
|
||||
PinboardMarkAsUnread: r.FormValue("pinboard_mark_as_unread") == "1",
|
||||
InstapaperEnabled: r.FormValue("instapaper_enabled") == "1",
|
||||
InstapaperUsername: r.FormValue("instapaper_username"),
|
||||
InstapaperPassword: r.FormValue("instapaper_password"),
|
||||
FeverEnabled: r.FormValue("fever_enabled") == "1",
|
||||
FeverUsername: r.FormValue("fever_username"),
|
||||
FeverPassword: r.FormValue("fever_password"),
|
||||
GoogleReaderEnabled: r.FormValue("googlereader_enabled") == "1",
|
||||
GoogleReaderUsername: r.FormValue("googlereader_username"),
|
||||
GoogleReaderPassword: r.FormValue("googlereader_password"),
|
||||
WallabagEnabled: r.FormValue("wallabag_enabled") == "1",
|
||||
WallabagOnlyURL: r.FormValue("wallabag_only_url") == "1",
|
||||
WallabagURL: r.FormValue("wallabag_url"),
|
||||
WallabagClientID: r.FormValue("wallabag_client_id"),
|
||||
WallabagClientSecret: r.FormValue("wallabag_client_secret"),
|
||||
WallabagUsername: r.FormValue("wallabag_username"),
|
||||
WallabagPassword: r.FormValue("wallabag_password"),
|
||||
NotionEnabled: r.FormValue("notion_enabled") == "1",
|
||||
NotionPageID: r.FormValue("notion_page_id"),
|
||||
NotionToken: r.FormValue("notion_token"),
|
||||
NunuxKeeperEnabled: r.FormValue("nunux_keeper_enabled") == "1",
|
||||
NunuxKeeperURL: r.FormValue("nunux_keeper_url"),
|
||||
NunuxKeeperAPIKey: r.FormValue("nunux_keeper_api_key"),
|
||||
EspialEnabled: r.FormValue("espial_enabled") == "1",
|
||||
EspialURL: r.FormValue("espial_url"),
|
||||
EspialAPIKey: r.FormValue("espial_api_key"),
|
||||
EspialTags: r.FormValue("espial_tags"),
|
||||
ReadwiseEnabled: r.FormValue("readwise_enabled") == "1",
|
||||
ReadwiseAPIKey: r.FormValue("readwise_api_key"),
|
||||
PocketEnabled: r.FormValue("pocket_enabled") == "1",
|
||||
PocketAccessToken: r.FormValue("pocket_access_token"),
|
||||
PocketConsumerKey: r.FormValue("pocket_consumer_key"),
|
||||
TelegramBotEnabled: r.FormValue("telegram_bot_enabled") == "1",
|
||||
TelegramBotToken: r.FormValue("telegram_bot_token"),
|
||||
TelegramBotChatID: r.FormValue("telegram_bot_chat_id"),
|
||||
LinkdingEnabled: r.FormValue("linkding_enabled") == "1",
|
||||
LinkdingURL: r.FormValue("linkding_url"),
|
||||
LinkdingAPIKey: r.FormValue("linkding_api_key"),
|
||||
LinkdingTags: r.FormValue("linkding_tags"),
|
||||
LinkdingMarkAsUnread: r.FormValue("linkding_mark_as_unread") == "1",
|
||||
MatrixBotEnabled: r.FormValue("matrix_bot_enabled") == "1",
|
||||
MatrixBotUser: r.FormValue("matrix_bot_user"),
|
||||
MatrixBotPassword: r.FormValue("matrix_bot_password"),
|
||||
MatrixBotURL: r.FormValue("matrix_bot_url"),
|
||||
MatrixBotChatID: r.FormValue("matrix_bot_chat_id"),
|
||||
AppriseEnabled: r.FormValue("apprise_enabled") == "1",
|
||||
AppriseURL: r.FormValue("apprise_url"),
|
||||
AppriseServicesURL: r.FormValue("apprise_services_url"),
|
||||
}
|
||||
}
|
126
internal/ui/form/settings.go
Normal file
126
internal/ui/form/settings.go
Normal file
|
@ -0,0 +1,126 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"miniflux.app/v2/internal/errors"
|
||||
"miniflux.app/v2/internal/model"
|
||||
)
|
||||
|
||||
// SettingsForm represents the settings form.
|
||||
type SettingsForm struct {
|
||||
Username string
|
||||
Password string
|
||||
Confirmation string
|
||||
Theme string
|
||||
Language string
|
||||
Timezone string
|
||||
EntryDirection string
|
||||
EntryOrder string
|
||||
EntriesPerPage int
|
||||
KeyboardShortcuts bool
|
||||
ShowReadingTime bool
|
||||
CustomCSS string
|
||||
EntrySwipe bool
|
||||
GestureNav string
|
||||
DisplayMode string
|
||||
DefaultReadingSpeed int
|
||||
CJKReadingSpeed int
|
||||
DefaultHomePage string
|
||||
CategoriesSortingOrder string
|
||||
MarkReadOnView bool
|
||||
}
|
||||
|
||||
// Merge updates the fields of the given user.
|
||||
func (s *SettingsForm) Merge(user *model.User) *model.User {
|
||||
user.Username = s.Username
|
||||
user.Theme = s.Theme
|
||||
user.Language = s.Language
|
||||
user.Timezone = s.Timezone
|
||||
user.EntryDirection = s.EntryDirection
|
||||
user.EntryOrder = s.EntryOrder
|
||||
user.EntriesPerPage = s.EntriesPerPage
|
||||
user.KeyboardShortcuts = s.KeyboardShortcuts
|
||||
user.ShowReadingTime = s.ShowReadingTime
|
||||
user.Stylesheet = s.CustomCSS
|
||||
user.EntrySwipe = s.EntrySwipe
|
||||
user.GestureNav = s.GestureNav
|
||||
user.DisplayMode = s.DisplayMode
|
||||
user.CJKReadingSpeed = s.CJKReadingSpeed
|
||||
user.DefaultReadingSpeed = s.DefaultReadingSpeed
|
||||
user.DefaultHomePage = s.DefaultHomePage
|
||||
user.CategoriesSortingOrder = s.CategoriesSortingOrder
|
||||
user.MarkReadOnView = s.MarkReadOnView
|
||||
|
||||
if s.Password != "" {
|
||||
user.Password = s.Password
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
// Validate makes sure the form values are valid.
|
||||
func (s *SettingsForm) Validate() error {
|
||||
if s.Username == "" || s.Theme == "" || s.Language == "" || s.Timezone == "" || s.EntryDirection == "" || s.DisplayMode == "" || s.DefaultHomePage == "" {
|
||||
return errors.NewLocalizedError("error.settings_mandatory_fields")
|
||||
}
|
||||
|
||||
if s.CJKReadingSpeed <= 0 || s.DefaultReadingSpeed <= 0 {
|
||||
return errors.NewLocalizedError("error.settings_reading_speed_is_positive")
|
||||
}
|
||||
|
||||
if s.Confirmation == "" {
|
||||
// Firefox insists on auto-completing the password field.
|
||||
// If the confirmation field is blank, the user probably
|
||||
// didn't intend to change their password.
|
||||
s.Password = ""
|
||||
} else if s.Password != "" {
|
||||
if s.Password != s.Confirmation {
|
||||
return errors.NewLocalizedError("error.different_passwords")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewSettingsForm returns a new SettingsForm.
|
||||
func NewSettingsForm(r *http.Request) *SettingsForm {
|
||||
entriesPerPage, err := strconv.ParseInt(r.FormValue("entries_per_page"), 10, 0)
|
||||
if err != nil {
|
||||
entriesPerPage = 0
|
||||
}
|
||||
defaultReadingSpeed, err := strconv.ParseInt(r.FormValue("default_reading_speed"), 10, 0)
|
||||
if err != nil {
|
||||
defaultReadingSpeed = 0
|
||||
}
|
||||
cjkReadingSpeed, err := strconv.ParseInt(r.FormValue("cjk_reading_speed"), 10, 0)
|
||||
if err != nil {
|
||||
cjkReadingSpeed = 0
|
||||
}
|
||||
return &SettingsForm{
|
||||
Username: r.FormValue("username"),
|
||||
Password: r.FormValue("password"),
|
||||
Confirmation: r.FormValue("confirmation"),
|
||||
Theme: r.FormValue("theme"),
|
||||
Language: r.FormValue("language"),
|
||||
Timezone: r.FormValue("timezone"),
|
||||
EntryDirection: r.FormValue("entry_direction"),
|
||||
EntryOrder: r.FormValue("entry_order"),
|
||||
EntriesPerPage: int(entriesPerPage),
|
||||
KeyboardShortcuts: r.FormValue("keyboard_shortcuts") == "1",
|
||||
ShowReadingTime: r.FormValue("show_reading_time") == "1",
|
||||
CustomCSS: r.FormValue("custom_css"),
|
||||
EntrySwipe: r.FormValue("entry_swipe") == "1",
|
||||
GestureNav: r.FormValue("gesture_nav"),
|
||||
DisplayMode: r.FormValue("display_mode"),
|
||||
DefaultReadingSpeed: int(defaultReadingSpeed),
|
||||
CJKReadingSpeed: int(cjkReadingSpeed),
|
||||
DefaultHomePage: r.FormValue("default_home_page"),
|
||||
CategoriesSortingOrder: r.FormValue("categories_sorting_order"),
|
||||
MarkReadOnView: r.FormValue("mark_read_on_view") == "1",
|
||||
}
|
||||
}
|
81
internal/ui/form/settings_test.go
Normal file
81
internal/ui/form/settings_test.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValid(t *testing.T) {
|
||||
settings := &SettingsForm{
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "hunter2",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
GestureNav: "tap",
|
||||
DefaultReadingSpeed: 35,
|
||||
CJKReadingSpeed: 25,
|
||||
DefaultHomePage: "unread",
|
||||
}
|
||||
|
||||
err := settings.Validate()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfirmationEmpty(t *testing.T) {
|
||||
settings := &SettingsForm{
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
GestureNav: "tap",
|
||||
DefaultReadingSpeed: 35,
|
||||
CJKReadingSpeed: 25,
|
||||
DefaultHomePage: "unread",
|
||||
}
|
||||
|
||||
err := settings.Validate()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if settings.Password != "" {
|
||||
t.Error("Password should have been cleared")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfirmationIncorrect(t *testing.T) {
|
||||
settings := &SettingsForm{
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "unter2",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
GestureNav: "tap",
|
||||
DefaultReadingSpeed: 35,
|
||||
CJKReadingSpeed: 25,
|
||||
DefaultHomePage: "unread",
|
||||
}
|
||||
|
||||
err := settings.Validate()
|
||||
if err == nil {
|
||||
t.Error("Validate should return an error")
|
||||
}
|
||||
}
|
80
internal/ui/form/subscription.go
Normal file
80
internal/ui/form/subscription.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"miniflux.app/v2/internal/errors"
|
||||
"miniflux.app/v2/internal/validator"
|
||||
)
|
||||
|
||||
// SubscriptionForm represents the subscription form.
|
||||
type SubscriptionForm struct {
|
||||
URL string
|
||||
CategoryID int64
|
||||
Crawler bool
|
||||
FetchViaProxy bool
|
||||
AllowSelfSignedCertificates bool
|
||||
UserAgent string
|
||||
Cookie string
|
||||
Username string
|
||||
Password string
|
||||
ScraperRules string
|
||||
RewriteRules string
|
||||
BlocklistRules string
|
||||
KeeplistRules string
|
||||
UrlRewriteRules string
|
||||
}
|
||||
|
||||
// Validate makes sure the form values are valid.
|
||||
func (s *SubscriptionForm) Validate() error {
|
||||
if s.URL == "" || s.CategoryID == 0 {
|
||||
return errors.NewLocalizedError("error.feed_mandatory_fields")
|
||||
}
|
||||
|
||||
if !validator.IsValidURL(s.URL) {
|
||||
return errors.NewLocalizedError("error.invalid_feed_url")
|
||||
}
|
||||
|
||||
if !validator.IsValidRegex(s.BlocklistRules) {
|
||||
return errors.NewLocalizedError("error.feed_invalid_blocklist_rule")
|
||||
}
|
||||
|
||||
if !validator.IsValidRegex(s.KeeplistRules) {
|
||||
return errors.NewLocalizedError("error.feed_invalid_keeplist_rule")
|
||||
}
|
||||
|
||||
if !validator.IsValidRegex(s.UrlRewriteRules) {
|
||||
return errors.NewLocalizedError("error.feed_invalid_urlrewrite_rule")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewSubscriptionForm returns a new SubscriptionForm.
|
||||
func NewSubscriptionForm(r *http.Request) *SubscriptionForm {
|
||||
categoryID, err := strconv.Atoi(r.FormValue("category_id"))
|
||||
if err != nil {
|
||||
categoryID = 0
|
||||
}
|
||||
|
||||
return &SubscriptionForm{
|
||||
URL: r.FormValue("url"),
|
||||
CategoryID: int64(categoryID),
|
||||
Crawler: r.FormValue("crawler") == "1",
|
||||
AllowSelfSignedCertificates: r.FormValue("allow_self_signed_certificates") == "1",
|
||||
FetchViaProxy: r.FormValue("fetch_via_proxy") == "1",
|
||||
UserAgent: r.FormValue("user_agent"),
|
||||
Cookie: r.FormValue("cookie"),
|
||||
Username: r.FormValue("feed_username"),
|
||||
Password: r.FormValue("feed_password"),
|
||||
ScraperRules: r.FormValue("scraper_rules"),
|
||||
RewriteRules: r.FormValue("rewrite_rules"),
|
||||
BlocklistRules: r.FormValue("blocklist_rules"),
|
||||
KeeplistRules: r.FormValue("keeplist_rules"),
|
||||
UrlRewriteRules: r.FormValue("urlrewrite_rules"),
|
||||
}
|
||||
}
|
73
internal/ui/form/user.go
Normal file
73
internal/ui/form/user.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package form // import "miniflux.app/v2/internal/ui/form"
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"miniflux.app/v2/internal/errors"
|
||||
"miniflux.app/v2/internal/model"
|
||||
)
|
||||
|
||||
// UserForm represents the user form.
|
||||
type UserForm struct {
|
||||
Username string
|
||||
Password string
|
||||
Confirmation string
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
// ValidateCreation validates user creation.
|
||||
func (u UserForm) ValidateCreation() error {
|
||||
if u.Username == "" || u.Password == "" || u.Confirmation == "" {
|
||||
return errors.NewLocalizedError("error.fields_mandatory")
|
||||
}
|
||||
|
||||
if u.Password != u.Confirmation {
|
||||
return errors.NewLocalizedError("error.different_passwords")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateModification validates user modification.
|
||||
func (u UserForm) ValidateModification() error {
|
||||
if u.Username == "" {
|
||||
return errors.NewLocalizedError("error.user_mandatory_fields")
|
||||
}
|
||||
|
||||
if u.Password != "" {
|
||||
if u.Password != u.Confirmation {
|
||||
return errors.NewLocalizedError("error.different_passwords")
|
||||
}
|
||||
|
||||
if len(u.Password) < 6 {
|
||||
return errors.NewLocalizedError("error.password_min_length")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Merge updates the fields of the given user.
|
||||
func (u UserForm) Merge(user *model.User) *model.User {
|
||||
user.Username = u.Username
|
||||
user.IsAdmin = u.IsAdmin
|
||||
|
||||
if u.Password != "" {
|
||||
user.Password = u.Password
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
// NewUserForm returns a new UserForm.
|
||||
func NewUserForm(r *http.Request) *UserForm {
|
||||
return &UserForm{
|
||||
Username: r.FormValue("username"),
|
||||
Password: r.FormValue("password"),
|
||||
Confirmation: r.FormValue("confirmation"),
|
||||
IsAdmin: r.FormValue("is_admin") == "1",
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue