Validate Keep list and Block list rules syntax

This commit is contained in:
Frédéric Guillot 2021-02-07 18:38:45 -08:00 committed by fguillot
parent 05fd83bd6f
commit e8d0360e64
19 changed files with 173 additions and 23 deletions

View File

@ -249,6 +249,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "Die Site-URL darf nicht leer sein.",
"error.feed_title_not_empty": "Der Feed-Titel darf nicht leer sein.",
"error.feed_category_not_found": "Diese Kategorie existiert nicht oder gehört nicht zu diesem Benutzer.",
"error.feed_invalid_blocklist_rule": "Die Sperrlistenregel ist ungültig.",
"error.feed_invalid_keeplist_rule": "Die Keep List-Regel ist ungültig.",
"error.user_mandatory_fields": "Der Benutzername ist obligatorisch.",
"error.api_key_already_exists": "Dieser API-Schlüssel ist bereits vorhanden.",
"error.unable_to_create_api_key": "Dieser API-Schlüssel kann nicht erstellt werden.",
@ -615,6 +617,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "The site URL cannot be empty.",
"error.feed_title_not_empty": "The feed title cannot be empty.",
"error.feed_category_not_found": "This category does not exist or does not belong to this user.",
"error.feed_invalid_blocklist_rule": "The block list rule is invalid.",
"error.feed_invalid_keeplist_rule": "The keep list rule is invalid.",
"error.user_mandatory_fields": "The username is mandatory.",
"error.api_key_already_exists": "This API Key already exists.",
"error.unable_to_create_api_key": "Unable to create this API Key.",
@ -953,6 +957,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "La URL del sitio no puede estar vacía.",
"error.feed_title_not_empty": "El título del feed no puede estar vacío.",
"error.feed_category_not_found": "Esta categoría no existe o no pertenece a este usuario.",
"error.feed_invalid_blocklist_rule": "La regla de la lista de bloqueo no es válida.",
"error.feed_invalid_keeplist_rule": "La regla de mantener la lista no es válida.",
"error.user_mandatory_fields": "El nombre de usuario es obligatorio.",
"error.api_key_already_exists": "Esta clave API ya existe.",
"error.unable_to_create_api_key": "No se puede crear esta clave API.",
@ -1295,6 +1301,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "L'URL du site ne peut pas être vide.",
"error.feed_title_not_empty": "Le titre du flux ne peut pas être vide.",
"error.feed_category_not_found": "Cette catégorie n'existe pas ou n'appartient pas à cet utilisateur.",
"error.feed_invalid_blocklist_rule": "La règle de blocage n'est pas valide.",
"error.feed_invalid_keeplist_rule": "La règle d'autorisation n'est pas valide.",
"error.user_mandatory_fields": "Le nom d'utilisateur est obligatoire.",
"error.api_key_already_exists": "Cette clé d'API existe déjà.",
"error.unable_to_create_api_key": "Impossible de créer cette clé d'API.",
@ -1314,7 +1322,7 @@ var translations = map[string]string{
"form.feed.label.rewrite_rules": "Règles de réécriture",
"form.feed.label.blocklist_rules": "Règles de blocage",
"form.feed.label.keeplist_rules": "Règles d'autorisation",
"form.feed.label.ignore_http_cache": "Ignore cache HTTP",
"form.feed.label.ignore_http_cache": "Ignorer le cache HTTP",
"form.feed.label.fetch_via_proxy": "Récupérer via proxy",
"form.feed.label.disabled": "Ne pas actualiser ce flux",
"form.category.label.title": "Titre",
@ -1657,6 +1665,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "L'URL del sito non può essere vuoto.",
"error.feed_title_not_empty": "Il titolo del feed non può essere vuoto.",
"error.feed_category_not_found": "Questa categoria non esiste o non appartiene a questo utente.",
"error.feed_invalid_blocklist_rule": "La regola dell'elenco di blocco non è valida.",
"error.feed_invalid_keeplist_rule": "La regola dell'elenco di conservazione non è valida.",
"error.user_mandatory_fields": "Il nome utente è obbligatorio.",
"error.api_key_already_exists": "Questa chiave API esiste già.",
"error.unable_to_create_api_key": "Impossibile creare questa chiave API.",
@ -1999,6 +2009,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "サイトのURLを空にすることはできません。",
"error.feed_title_not_empty": "フィードのタイトルを空にすることはできません。",
"error.feed_category_not_found": "このカテゴリは存在しないか、このユーザーに属していません。",
"error.feed_invalid_blocklist_rule": "ブロックリストルールが無効です。",
"error.feed_invalid_keeplist_rule": "リストの保持ルールが無効です。",
"error.user_mandatory_fields": "ユーザー名が必要です。",
"error.api_key_already_exists": "このAPIキーは既に存在します。",
"error.unable_to_create_api_key": "このAPIキーを作成できません。",
@ -2341,6 +2353,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "De site-URL mag niet leeg zijn.",
"error.feed_title_not_empty": "De feedtitel mag niet leeg zijn.",
"error.feed_category_not_found": "Deze categorie bestaat niet of behoort niet tot deze gebruiker.",
"error.feed_invalid_blocklist_rule": "De regel voor de blokkeerlijst is ongeldig.",
"error.feed_invalid_keeplist_rule": "De regel voor het bewaren van een lijst is ongeldig.",
"error.user_mandatory_fields": "Gebruikersnaam is verplicht",
"error.api_key_already_exists": "This API Key already exists.",
"error.unable_to_create_api_key": "Kan deze API-sleutel niet maken.",
@ -2703,6 +2717,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "Adres URL witryny nie może być pusty.",
"error.feed_title_not_empty": "Tytuł kanału nie może być pusty.",
"error.feed_category_not_found": "Ta kategoria nie istnieje lub nie należy do tego użytkownika.",
"error.feed_invalid_blocklist_rule": "Reguła listy zablokowanych jest nieprawidłowa.",
"error.feed_invalid_keeplist_rule": "Reguła listy zachowania jest nieprawidłowa.",
"error.user_mandatory_fields": "Nazwa użytkownika jest obowiązkowa.",
"error.api_key_already_exists": "Deze API-sleutel bestaat al.",
"error.unable_to_create_api_key": "Nie można utworzyć tego klucza API.",
@ -3069,6 +3085,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "O URL do site não pode estar vazio.",
"error.feed_title_not_empty": "O título do feed não pode estar vazio.",
"error.feed_category_not_found": "Esta categoria não existe ou não pertence a este usuário.",
"error.feed_invalid_blocklist_rule": "A regra da lista de bloqueio é inválida.",
"error.feed_invalid_keeplist_rule": "A regra de manutenção da lista é inválida.",
"error.user_mandatory_fields": "O nome de usuário é obrigatório.",
"error.api_key_already_exists": "Essa chave de API já existe.",
"error.unable_to_create_api_key": "Não foi possível criar uma chave de API.",
@ -3413,6 +3431,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "URL сайта не может быть пустым.",
"error.feed_title_not_empty": "Заголовок фида не может быть пустым.",
"error.feed_category_not_found": "Эта категория не существует или не принадлежит этому пользователю.",
"error.feed_invalid_blocklist_rule": "Правило черного списка недействительно.",
"error.feed_invalid_keeplist_rule": "Правило списка хранения недействительно.",
"error.user_mandatory_fields": "Имя пользователя обязательно.",
"error.api_key_already_exists": "Этот ключ API уже существует.",
"error.unable_to_create_api_key": "Невозможно создать этот ключ API.",
@ -3759,6 +3779,8 @@ var translations = map[string]string{
"error.site_url_not_empty": "网站网址不能为空。",
"error.feed_title_not_empty": "供稿标题不能为空。",
"error.feed_category_not_found": "此类别不存在或不属于该用户。",
"error.feed_invalid_blocklist_rule": "阻止列表规则无效。",
"error.feed_invalid_keeplist_rule": "保留列表规则无效。",
"error.user_mandatory_fields": "必须填写用户名",
"error.api_key_already_exists": "此API密钥已存在。",
"error.unable_to_create_api_key": "无法创建此API密钥。",
@ -3871,15 +3893,15 @@ var translations = map[string]string{
}
var translationsChecksums = map[string]string{
"de_DE": "96616242d64bfca6bcc27762260aac38a3014ae854dfe4d85711491f7e0e52a2",
"en_US": "0718463b2edc0157dba7b26c033bcfa36181e57addd613a19ce60e6c6b34cb19",
"es_ES": "fc767762d1eb5cd44d89aab99a58a0c28b910ba06457d7ffe1b21092d473bb8e",
"fr_FR": "3abdb817b699ffb2c9f3c2316879c65b96510ff3e6a875860fcccdd063b29e63",
"it_IT": "2d2aa46e81f48494c08b78963d88d6522395856bd25f4b1504403da1f8d531e8",
"ja_JP": "7c1098e38962f4d285b957f7db428b28d562d1fe3b16117c0ac0340870cd43b0",
"nl_NL": "43093afdfa7d692d83455f5e4f3d36d4e725c704796961b749a84ba27ddbbd0b",
"pl_PL": "eb0baf99b46f5440a32084453091272f57c5f676b595640016f168fb65e439b7",
"pt_BR": "9ed1a472f60e65c4f8309417a3af17572299cd23c25ae6e1d368996578963b25",
"ru_RU": "de2cda1638754b7c3376749fa7d62d75d3594543465c1f78f801fe6c08d4eb2f",
"zh_CN": "07f1fb9efeb93f2d45b71c7028b50fe5bca378c307d1e2dadd0821fabd074918",
"de_DE": "204b8359228926129612defadb82b425ca6d76a60606572a5e66b4313753b6b8",
"en_US": "836c34115c6e190e9b77e894ab998193bdc5dae204636084994a09b6274ff41f",
"es_ES": "b190315004d23bfeda4123e6f77613bdcb78335b0b6a2876dd0e1bc76c428eaa",
"fr_FR": "7be464741f4301dd3a6ace3fd66f471884dbbd1f9a2866a805502227382b94a7",
"it_IT": "e2027bf6c5ee384d0bf776c4fb04fd99b5c4e18c694db4d7ff09529b9fe96d17",
"ja_JP": "33ac3c96003b95222dc1318f6dc1e929c8b75e2415700e7b544abfbe57b6eb0a",
"nl_NL": "dbf1343301ed35161f8deebd25726bc39d6a1bfdeb198ac555b1a0c72e16d96d",
"pl_PL": "8c646402462d62235245229f3a9f0297cdf6ac2f53df1e25508075e43a1ccf4e",
"pt_BR": "2d613ce5fd8b00da9df5c9cf1f675839cdfc3e4c5646b0cc949f0bf18aca59d0",
"ru_RU": "e6c4d0467051235d28c0329404e9ec8a7d353563b789f69e6cada2099d816f5d",
"zh_CN": "51ec39c564c11373b1574ed35d798dab61036d8cbeb6c807116e5dbf7443f31c",
}

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "Die Site-URL darf nicht leer sein.",
"error.feed_title_not_empty": "Der Feed-Titel darf nicht leer sein.",
"error.feed_category_not_found": "Diese Kategorie existiert nicht oder gehört nicht zu diesem Benutzer.",
"error.feed_invalid_blocklist_rule": "Die Sperrlistenregel ist ungültig.",
"error.feed_invalid_keeplist_rule": "Die Keep List-Regel ist ungültig.",
"error.user_mandatory_fields": "Der Benutzername ist obligatorisch.",
"error.api_key_already_exists": "Dieser API-Schlüssel ist bereits vorhanden.",
"error.unable_to_create_api_key": "Dieser API-Schlüssel kann nicht erstellt werden.",

View File

@ -248,6 +248,8 @@
"error.site_url_not_empty": "The site URL cannot be empty.",
"error.feed_title_not_empty": "The feed title cannot be empty.",
"error.feed_category_not_found": "This category does not exist or does not belong to this user.",
"error.feed_invalid_blocklist_rule": "The block list rule is invalid.",
"error.feed_invalid_keeplist_rule": "The keep list rule is invalid.",
"error.user_mandatory_fields": "The username is mandatory.",
"error.api_key_already_exists": "This API Key already exists.",
"error.unable_to_create_api_key": "Unable to create this API Key.",

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "La URL del sitio no puede estar vacía.",
"error.feed_title_not_empty": "El título del feed no puede estar vacío.",
"error.feed_category_not_found": "Esta categoría no existe o no pertenece a este usuario.",
"error.feed_invalid_blocklist_rule": "La regla de la lista de bloqueo no es válida.",
"error.feed_invalid_keeplist_rule": "La regla de mantener la lista no es válida.",
"error.user_mandatory_fields": "El nombre de usuario es obligatorio.",
"error.api_key_already_exists": "Esta clave API ya existe.",
"error.unable_to_create_api_key": "No se puede crear esta clave API.",

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "L'URL du site ne peut pas être vide.",
"error.feed_title_not_empty": "Le titre du flux ne peut pas être vide.",
"error.feed_category_not_found": "Cette catégorie n'existe pas ou n'appartient pas à cet utilisateur.",
"error.feed_invalid_blocklist_rule": "La règle de blocage n'est pas valide.",
"error.feed_invalid_keeplist_rule": "La règle d'autorisation n'est pas valide.",
"error.user_mandatory_fields": "Le nom d'utilisateur est obligatoire.",
"error.api_key_already_exists": "Cette clé d'API existe déjà.",
"error.unable_to_create_api_key": "Impossible de créer cette clé d'API.",
@ -263,7 +265,7 @@
"form.feed.label.rewrite_rules": "Règles de réécriture",
"form.feed.label.blocklist_rules": "Règles de blocage",
"form.feed.label.keeplist_rules": "Règles d'autorisation",
"form.feed.label.ignore_http_cache": "Ignore cache HTTP",
"form.feed.label.ignore_http_cache": "Ignorer le cache HTTP",
"form.feed.label.fetch_via_proxy": "Récupérer via proxy",
"form.feed.label.disabled": "Ne pas actualiser ce flux",
"form.category.label.title": "Titre",

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "L'URL del sito non può essere vuoto.",
"error.feed_title_not_empty": "Il titolo del feed non può essere vuoto.",
"error.feed_category_not_found": "Questa categoria non esiste o non appartiene a questo utente.",
"error.feed_invalid_blocklist_rule": "La regola dell'elenco di blocco non è valida.",
"error.feed_invalid_keeplist_rule": "La regola dell'elenco di conservazione non è valida.",
"error.user_mandatory_fields": "Il nome utente è obbligatorio.",
"error.api_key_already_exists": "Questa chiave API esiste già.",
"error.unable_to_create_api_key": "Impossibile creare questa chiave API.",

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "サイトのURLを空にすることはできません。",
"error.feed_title_not_empty": "フィードのタイトルを空にすることはできません。",
"error.feed_category_not_found": "このカテゴリは存在しないか、このユーザーに属していません。",
"error.feed_invalid_blocklist_rule": "ブロックリストルールが無効です。",
"error.feed_invalid_keeplist_rule": "リストの保持ルールが無効です。",
"error.user_mandatory_fields": "ユーザー名が必要です。",
"error.api_key_already_exists": "このAPIキーは既に存在します。",
"error.unable_to_create_api_key": "このAPIキーを作成できません。",

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "De site-URL mag niet leeg zijn.",
"error.feed_title_not_empty": "De feedtitel mag niet leeg zijn.",
"error.feed_category_not_found": "Deze categorie bestaat niet of behoort niet tot deze gebruiker.",
"error.feed_invalid_blocklist_rule": "De regel voor de blokkeerlijst is ongeldig.",
"error.feed_invalid_keeplist_rule": "De regel voor het bewaren van een lijst is ongeldig.",
"error.user_mandatory_fields": "Gebruikersnaam is verplicht",
"error.api_key_already_exists": "This API Key already exists.",
"error.unable_to_create_api_key": "Kan deze API-sleutel niet maken.",

View File

@ -246,6 +246,8 @@
"error.site_url_not_empty": "Adres URL witryny nie może być pusty.",
"error.feed_title_not_empty": "Tytuł kanału nie może być pusty.",
"error.feed_category_not_found": "Ta kategoria nie istnieje lub nie należy do tego użytkownika.",
"error.feed_invalid_blocklist_rule": "Reguła listy zablokowanych jest nieprawidłowa.",
"error.feed_invalid_keeplist_rule": "Reguła listy zachowania jest nieprawidłowa.",
"error.user_mandatory_fields": "Nazwa użytkownika jest obowiązkowa.",
"error.api_key_already_exists": "Deze API-sleutel bestaat al.",
"error.unable_to_create_api_key": "Nie można utworzyć tego klucza API.",

View File

@ -244,6 +244,8 @@
"error.site_url_not_empty": "O URL do site não pode estar vazio.",
"error.feed_title_not_empty": "O título do feed não pode estar vazio.",
"error.feed_category_not_found": "Esta categoria não existe ou não pertence a este usuário.",
"error.feed_invalid_blocklist_rule": "A regra da lista de bloqueio é inválida.",
"error.feed_invalid_keeplist_rule": "A regra de manutenção da lista é inválida.",
"error.user_mandatory_fields": "O nome de usuário é obrigatório.",
"error.api_key_already_exists": "Essa chave de API já existe.",
"error.unable_to_create_api_key": "Não foi possível criar uma chave de API.",

View File

@ -246,6 +246,8 @@
"error.site_url_not_empty": "URL сайта не может быть пустым.",
"error.feed_title_not_empty": "Заголовок фида не может быть пустым.",
"error.feed_category_not_found": "Эта категория не существует или не принадлежит этому пользователю.",
"error.feed_invalid_blocklist_rule": "Правило черного списка недействительно.",
"error.feed_invalid_keeplist_rule": "Правило списка хранения недействительно.",
"error.user_mandatory_fields": "Имя пользователя обязательно.",
"error.api_key_already_exists": "Этот ключ API уже существует.",
"error.unable_to_create_api_key": "Невозможно создать этот ключ API.",

View File

@ -242,6 +242,8 @@
"error.site_url_not_empty": "网站网址不能为空。",
"error.feed_title_not_empty": "供稿标题不能为空。",
"error.feed_category_not_found": "此类别不存在或不属于该用户。",
"error.feed_invalid_blocklist_rule": "阻止列表规则无效。",
"error.feed_invalid_keeplist_rule": "保留列表规则无效。",
"error.user_mandatory_fields": "必须填写用户名",
"error.api_key_already_exists": "此API密钥已存在。",
"error.unable_to_create_api_key": "无法创建此API密钥。",

View File

@ -202,6 +202,55 @@ func TestCreateFeedWithScraperRule(t *testing.T) {
}
}
func TestCreateFeedWithKeeplistRule(t *testing.T) {
client := createClient(t)
categories, err := client.Categories()
if err != nil {
t.Fatal(err)
}
feedID, err := client.CreateFeed(&miniflux.FeedCreationRequest{
FeedURL: testFeedURL,
CategoryID: categories[0].ID,
KeeplistRules: "(?i)miniflux",
})
if err != nil {
t.Fatal(err)
}
if feedID == 0 {
t.Fatalf(`Invalid feed ID, got %q`, feedID)
}
feed, err := client.Feed(feedID)
if err != nil {
t.Fatal(err)
}
if feed.KeeplistRules != "(?i)miniflux" {
t.Error(`The feed should have the custom keep list rule saved`)
}
}
func TestCreateFeedWithInvalidBlocklistRule(t *testing.T) {
client := createClient(t)
categories, err := client.Categories()
if err != nil {
t.Fatal(err)
}
_, err = client.CreateFeed(&miniflux.FeedCreationRequest{
FeedURL: testFeedURL,
CategoryID: categories[0].ID,
BlocklistRules: "[",
})
if err == nil {
t.Fatal(`Feed with invalid block list rule should not be created`)
}
}
func TestUpdateFeedURL(t *testing.T) {
client := createClient(t)
feed, _ := createFeed(t, client)

View File

@ -58,10 +58,12 @@ func (h *handler) updateFeed(w http.ResponseWriter, r *http.Request) {
view.Set("defaultUserAgent", config.Opts.HTTPClientUserAgent())
feedModificationRequest := &model.FeedModificationRequest{
FeedURL: model.OptionalString(feedForm.FeedURL),
SiteURL: model.OptionalString(feedForm.SiteURL),
Title: model.OptionalString(feedForm.Title),
CategoryID: model.OptionalInt64(feedForm.CategoryID),
FeedURL: model.OptionalString(feedForm.FeedURL),
SiteURL: model.OptionalString(feedForm.SiteURL),
Title: model.OptionalString(feedForm.Title),
CategoryID: model.OptionalInt64(feedForm.CategoryID),
BlocklistRules: model.OptionalString(feedForm.BlocklistRules),
KeeplistRules: model.OptionalString(feedForm.KeeplistRules),
}
if validationErr := validator.ValidateFeedModification(h.store, loggedUser.ID, feedModificationRequest); validationErr != nil {

View File

@ -9,6 +9,7 @@ import (
"strconv"
"miniflux.app/errors"
"miniflux.app/validator"
)
// SubscriptionForm represents the subscription form.
@ -32,6 +33,18 @@ func (s *SubscriptionForm) Validate() error {
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")
}
return nil
}

View File

@ -15,7 +15,7 @@ func ValidateFeedCreation(store *storage.Storage, userID int64, request *model.F
return NewValidationError("error.feed_mandatory_fields")
}
if !isValidURL(request.FeedURL) {
if !IsValidURL(request.FeedURL) {
return NewValidationError("error.invalid_feed_url")
}
@ -27,6 +27,14 @@ func ValidateFeedCreation(store *storage.Storage, userID int64, request *model.F
return NewValidationError("error.feed_category_not_found")
}
if !IsValidRegex(request.BlocklistRules) {
return NewValidationError("error.feed_invalid_blocklist_rule")
}
if !IsValidRegex(request.KeeplistRules) {
return NewValidationError("error.feed_invalid_keeplist_rule")
}
return nil
}
@ -37,7 +45,7 @@ func ValidateFeedModification(store *storage.Storage, userID int64, request *mod
return NewValidationError("error.feed_url_not_empty")
}
if !isValidURL(*request.FeedURL) {
if !IsValidURL(*request.FeedURL) {
return NewValidationError("error.invalid_feed_url")
}
}
@ -47,7 +55,7 @@ func ValidateFeedModification(store *storage.Storage, userID int64, request *mod
return NewValidationError("error.site_url_not_empty")
}
if !isValidURL(*request.SiteURL) {
if !IsValidURL(*request.SiteURL) {
return NewValidationError("error.invalid_site_url")
}
}
@ -64,5 +72,17 @@ func ValidateFeedModification(store *storage.Storage, userID int64, request *mod
}
}
if request.BlocklistRules != nil {
if !IsValidRegex(*request.BlocklistRules) {
return NewValidationError("error.feed_invalid_blocklist_rule")
}
}
if request.KeeplistRules != nil {
if !IsValidRegex(*request.KeeplistRules) {
return NewValidationError("error.feed_invalid_keeplist_rule")
}
}
return nil
}

View File

@ -8,7 +8,7 @@ import "miniflux.app/model"
// ValidateSubscriptionDiscovery validates subscription discovery requests.
func ValidateSubscriptionDiscovery(request *model.SubscriptionDiscoveryRequest) *ValidationError {
if !isValidURL(request.URL) {
if !IsValidURL(request.URL) {
return NewValidationError("error.invalid_site_url")
}

View File

@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"net/url"
"regexp"
"miniflux.app/locale"
)
@ -53,7 +54,14 @@ func ValidateDirection(direction string) error {
return fmt.Errorf(`Invalid direction, valid direction values are: "asc" or "desc"`)
}
func isValidURL(absoluteURL string) bool {
// IsValidRegex verifies if the regex can be compiled.
func IsValidRegex(expr string) bool {
_, err := regexp.Compile(expr)
return err == nil
}
// IsValidURL verifies if the provided value is a valid absolute URL.
func IsValidURL(absoluteURL string) bool {
_, err := url.ParseRequestURI(absoluteURL)
return err == nil
}

View File

@ -14,7 +14,7 @@ func TestIsValidURL(t *testing.T) {
}
for link, expected := range scenarios {
result := isValidURL(link)
result := IsValidURL(link)
if result != expected {
t.Errorf(`Unexpected result, got %v instead of %v`, result, expected)
}
@ -46,3 +46,17 @@ func TestValidateDirection(t *testing.T) {
t.Error(`An invalid direction should generate a error`)
}
}
func TestIsValidRegex(t *testing.T) {
scenarios := map[string]bool{
"(?i)miniflux": true,
"[": false,
}
for expr, expected := range scenarios {
result := IsValidRegex(expr)
if result != expected {
t.Errorf(`Unexpected result, got %v instead of %v`, result, expected)
}
}
}