From 27a54321761e1575e975689c41c1be9e447d79bc Mon Sep 17 00:00:00 2001 From: trivernis Date: Tue, 8 Feb 2022 20:34:10 +0100 Subject: [PATCH] Enforce tags to be lowercase Signed-off-by: trivernis --- mediarepo-daemon/mediarepo-core/src/utils.rs | 1 + .../mediarepo-logic/src/dto/namespace.rs | 4 +-- .../src/api/models/FilterQueryBuilder.ts | 5 ++-- .../filter-input/filter-input.component.ts | 5 ++-- .../input/tag-input/tag-input.component.ts | 25 +++---------------- mediarepo-ui/src/app/utils/tag-utils.ts | 18 +++++++++++++ 6 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 mediarepo-ui/src/app/utils/tag-utils.ts diff --git a/mediarepo-daemon/mediarepo-core/src/utils.rs b/mediarepo-daemon/mediarepo-core/src/utils.rs index 4d901e8..74f6b75 100644 --- a/mediarepo-daemon/mediarepo-core/src/utils.rs +++ b/mediarepo-daemon/mediarepo-core/src/utils.rs @@ -9,6 +9,7 @@ use crate::error::RepoResult; /// Parses a normalized tag into its two components of namespace and tag pub fn parse_namespace_and_tag(norm_tag: String) -> (Option, String) { norm_tag + .to_lowercase() .split_once(':') .map(|(n, t)| (Some(n.trim().to_string()), t.trim().to_string())) .unwrap_or((None, norm_tag.trim().to_string())) diff --git a/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs b/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs index 2729ecc..50d7b0a 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dto/namespace.rs @@ -7,7 +7,7 @@ pub struct NamespaceDto { impl NamespaceDto { pub(crate) fn new(model: namespace::Model) -> Self { - Self {model} + Self { model } } pub fn id(&self) -> i64 { @@ -17,4 +17,4 @@ impl NamespaceDto { pub fn name(&self) -> &String { &self.model.name } -} \ No newline at end of file +} diff --git a/mediarepo-ui/src/api/models/FilterQueryBuilder.ts b/mediarepo-ui/src/api/models/FilterQueryBuilder.ts index 48c1a1f..95e7827 100644 --- a/mediarepo-ui/src/api/models/FilterQueryBuilder.ts +++ b/mediarepo-ui/src/api/models/FilterQueryBuilder.ts @@ -1,4 +1,5 @@ import {FileStatus, FilterExpression, FilterQuery, PropertyQuery, ValueComparator} from "../api-types/files"; +import {normalizeTag} from "../../app/utils/tag-utils"; export type Comparator = "Less" | "Equal" | "Greater" | "Between"; export type PropertyType = @@ -14,7 +15,7 @@ export type PropertyType = export class FilterQueryBuilder { public static tag(tag: string, negate: boolean): FilterQuery { - return { Tag: { tag, negate } }; + return { Tag: { tag: normalizeTag(tag), negate } }; } public static status(status: FileStatus): FilterQuery { @@ -74,7 +75,7 @@ export class FilterQueryBuilder { } public static buildFilterFromString(filterStr: string): FilterQuery | undefined { - filterStr = filterStr.trim(); + filterStr = filterStr.trim().toLowerCase(); if (filterStr.startsWith(".")) { const cleanFilter = filterStr.replace(/^\./, ""); diff --git a/mediarepo-ui/src/app/components/shared/input/filter-input/filter-input.component.ts b/mediarepo-ui/src/app/components/shared/input/filter-input/filter-input.component.ts index d12cd95..a28c07a 100644 --- a/mediarepo-ui/src/app/components/shared/input/filter-input/filter-input.component.ts +++ b/mediarepo-ui/src/app/components/shared/input/filter-input/filter-input.component.ts @@ -6,6 +6,7 @@ import {FilterExpression, FilterQuery} from "../../../../../api/api-types/files" import {debounceTime, map, startWith} from "rxjs/operators"; import {compareSearchResults} from "../../../../utils/compare-utils"; import {FilterQueryBuilder} from "../../../../../api/models/FilterQueryBuilder"; +import {normalizeTag} from "../../../../utils/tag-utils"; type AutocompleteEntry = { value: string, @@ -122,11 +123,11 @@ export class FilterInputComponent implements OnChanges { } private filterAutosuggestFilters(filterValue: string): AutocompleteEntry[] { - const queryParts = filterValue.split(/\s+or\s+/gi); + const queryParts = filterValue.toLowerCase().split(/\s+or\s+/gi); const latestQuery = queryParts[queryParts.length - 1]; const trimmedValue = latestQuery.trim(); let isNegation = trimmedValue.startsWith("-"); - const cleanValue = trimmedValue.replace(/^-/, ""); + const cleanValue = normalizeTag(trimmedValue.replace(/^-/, "")); const autosuggestTags = this.tagsForAutocomplete.filter(t => t.includes(cleanValue)).map(t => isNegation ? "-" + t : t); let propertyQuerySuggestions: string[] = []; diff --git a/mediarepo-ui/src/app/components/shared/input/tag-input/tag-input.component.ts b/mediarepo-ui/src/app/components/shared/input/tag-input/tag-input.component.ts index 32f4b15..b682009 100644 --- a/mediarepo-ui/src/app/components/shared/input/tag-input/tag-input.component.ts +++ b/mediarepo-ui/src/app/components/shared/input/tag-input/tag-input.component.ts @@ -5,6 +5,7 @@ import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete"; import {Observable} from "rxjs"; import {debounceTime, map, startWith} from "rxjs/operators"; import {compareSearchResults} from "../../../../utils/compare-utils"; +import {normalizeTag} from "../../../../utils/tag-utils"; @Component({ selector: "app-tag-input", @@ -35,24 +36,6 @@ export class TagInputComponent implements OnChanges { ); } - /** - * Normalizes the tag by removing whitespaces - * @param {string} tag - * @returns {string} - * @private - */ - private static normalizeTag(tag: string): string { - let normalizedTag = tag.trim(); - let parts = normalizedTag.split(":"); - - if (parts.length > 1) { - const namespace = parts.shift()!.trim(); - const name = parts.join(":").trim(); - return namespace + ":" + name; - } else { - return normalizedTag; - } - } ngOnChanges(changes: SimpleChanges): void { if (changes["availableTags"]) { @@ -72,7 +55,7 @@ export class TagInputComponent implements OnChanges { } private addTag(value: string) { - const tag = TagInputComponent.normalizeTag(value); + const tag = normalizeTag(value); if (tag.length > 0 && (this.allowInvalid || this.checkTagValid(tag))) { this.tagAdded.emit(tag); this.formControl.setValue(""); @@ -81,7 +64,7 @@ export class TagInputComponent implements OnChanges { } private filterSuggestionTag(tag: string) { - let normalizedTag = TagInputComponent.normalizeTag(tag); + let normalizedTag = normalizeTag(tag); const negated = normalizedTag.startsWith("-") && this.allowNegation; normalizedTag = this.allowNegation ? normalizedTag.replace( /^-/, @@ -100,7 +83,7 @@ export class TagInputComponent implements OnChanges { .slice(0, 50); if (containsWildcard) { - autocompleteTags.unshift(TagInputComponent.normalizeTag(tag)); + autocompleteTags.unshift(normalizeTag(tag)); } return autocompleteTags; diff --git a/mediarepo-ui/src/app/utils/tag-utils.ts b/mediarepo-ui/src/app/utils/tag-utils.ts new file mode 100644 index 0000000..bfb74f7 --- /dev/null +++ b/mediarepo-ui/src/app/utils/tag-utils.ts @@ -0,0 +1,18 @@ +/** + * Normalizes the tag by removing whitespaces and enforcing lowercase + * @param {string} tag + * @returns {string} + * @private + */ +export function normalizeTag(tag: string): string { + let normalizedTag = tag.trim().toLowerCase(); + let parts = normalizedTag.split(":"); + + if (parts.length > 1) { + const namespace = parts.shift()!.trim(); + const name = parts.join(":").trim(); + return namespace + ":" + name; + } else { + return normalizedTag; + } +}