Backend: Ignore image unique IDs that are not standard UUIDs

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer
2020-07-23 15:34:20 +02:00
parent 514968adf0
commit 91a1a1ca27
11 changed files with 92 additions and 41 deletions

View File

@@ -3,6 +3,8 @@ package meta
import (
"math"
"time"
"github.com/photoprism/photoprism/pkg/rnd"
)
// Data represents image meta data.
@@ -83,12 +85,12 @@ func (data Data) Megapixels() int {
// HasDocumentID returns true if a DocumentID exists.
func (data Data) HasDocumentID() bool {
return len(data.DocumentID) >= 15
return rnd.IsUUID(data.DocumentID)
}
// HasInstanceID returns true if an InstanceID exists.
func (data Data) HasInstanceID() bool {
return len(data.InstanceID) >= 15
return rnd.IsUUID(data.InstanceID)
}
// HasTimeAndPlace if data contains a time and gps position.

View File

@@ -80,15 +80,23 @@ func TestData_Megapixels(t *testing.T) {
}
func TestData_HasDocumentID(t *testing.T) {
t.Run("true", func(t *testing.T) {
t.Run("6ba7b810-9dad-11d1-80b4-00c04fd430c8", func(t *testing.T) {
data := Data{
DocumentID: "asdfg12345hjyt6",
DocumentID: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
}
assert.Equal(t, true, data.HasDocumentID())
})
t.Run("false", func(t *testing.T) {
t.Run("asdfg12345hjyt6", func(t *testing.T) {
data := Data{
DocumentID: "asdfg12345hjyt6",
}
assert.Equal(t, false, data.HasDocumentID())
})
t.Run("asdfg12345hj", func(t *testing.T) {
data := Data{
DocumentID: "asdfg12345hj",
}
@@ -100,7 +108,7 @@ func TestData_HasDocumentID(t *testing.T) {
func TestData_HasInstanceID(t *testing.T) {
t.Run("true", func(t *testing.T) {
data := Data{
InstanceID: "asdfg12345hjyt6",
InstanceID: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
}
assert.Equal(t, true, data.HasInstanceID())

View File

@@ -16,6 +16,7 @@ import (
"github.com/dsoprea/go-png-image-structure"
"github.com/dsoprea/go-tiff-image-structure"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/rnd"
"github.com/photoprism/photoprism/pkg/txt"
"gopkg.in/ugjka/go-tz.v2/tz"
)
@@ -280,7 +281,9 @@ func (data *Data) Exif(fileName string, fileType fs.FileType) (err error) {
}
if value, ok := tags["ImageUniqueID"]; ok {
data.DocumentID = SanitizeUID(value)
if id := rnd.SanitizeUUID(value); id != "" {
data.DocumentID = id
}
}
if value, ok := tags["PixelXDimension"]; ok {

View File

@@ -8,6 +8,7 @@ import (
"strings"
"time"
"github.com/photoprism/photoprism/pkg/rnd"
"github.com/photoprism/photoprism/pkg/txt"
"github.com/tidwall/gjson"
"gopkg.in/ugjka/go-tz.v2/tz"
@@ -165,13 +166,13 @@ func (data *Data) Exiftool(jsonData []byte, originalName string) (err error) {
}
// Validate and normalize optional DocumentID.
if len(data.DocumentID) > 0 {
data.DocumentID = SanitizeUID(data.DocumentID)
if data.DocumentID != "" {
data.DocumentID = rnd.SanitizeUUID(data.DocumentID)
}
// Validate and normalize optional InstanceID.
if len(data.InstanceID) > 0 {
data.InstanceID = SanitizeUID(data.InstanceID)
if data.InstanceID != "" {
data.InstanceID = rnd.SanitizeUUID(data.InstanceID)
}
if data.Projection == "equirectangular" {

View File

@@ -275,7 +275,7 @@ func TestJSON(t *testing.T) {
// t.Logf("DATA: %+v", data)
assert.Equal(t, "4b1fef2d1cf4a5be38b263e0637edead", data.DocumentID)
assert.Equal(t, "", data.DocumentID)
assert.Equal(t, "dafbfeb8-a129-4e7c-9cf0-e7996a701cdb", data.InstanceID)
assert.Equal(t, CodecJpeg, data.Codec)
assert.Equal(t, "0s", data.Duration.String())

View File

@@ -15,11 +15,10 @@ func TestDirs(t *testing.T) {
t.Fatal(err)
}
assert.Len(t, result, 7)
assert.Contains(t, result, "/directory")
assert.Contains(t, result, "/directory/subdirectory")
assert.Contains(t, result, "/linked")
assert.Contains(t, result, "/linked/photoprism")
assert.Contains(t, result, "/linked/photoprism/sub")
})
t.Run("recursive no-symlinks", func(t *testing.T) {

View File

@@ -29,20 +29,6 @@ func BenchmarkRandomPassword(b *testing.B) {
}
}
func TestUUID(t *testing.T) {
for n := 0; n < 5; n++ {
uuid := UUID()
t.Logf("token: %s", uuid)
assert.Equal(t, 36, len(uuid))
}
}
func BenchmarkUUID(b *testing.B) {
for n := 0; n < b.N; n++ {
UUID()
}
}
func BenchmarkRandomToken4(b *testing.B) {
for n := 0; n < b.N; n++ {
Token(4)

View File

@@ -58,11 +58,6 @@ func IsLowerAlnum(s string) bool {
return true
}
// Returns true if the string looks like a standard UUID.
func IsUUID(s string) bool {
return len(s) == 36 && IsHex(s)
}
// IsUID returns true if string is a seemingly unique id.
func IsUID(s string, prefix byte) bool {
// Regular UUID.

View File

@@ -45,14 +45,6 @@ func TestIsHex(t *testing.T) {
}
func TestIsUUID(t *testing.T) {
assert.True(t, IsUUID("dafbfeb8-a129-4e7c-9cf0-e7996a701cdb"))
assert.True(t, IsUUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
assert.False(t, IsUUID("55785BAC-9H4B-4747-B090-EE123FFEE437"))
assert.True(t, IsUUID("550e8400-e29b-11d4-a716-446655440000"))
assert.False(t, IsUUID("4B1FEF2D1CF4A5BE38B263E0637EDEAD"))
}
func TestIsUID(t *testing.T) {
assert.True(t, IsUID("lt9k3pw1wowuy3c2", 'l'))
assert.True(t, IsUID("dafbfeb8-a129-4e7c-9cf0-e7996a701cdb", 'l'))

View File

@@ -1,6 +1,8 @@
package rnd
import (
"strings"
uuid "github.com/satori/go.uuid"
)
@@ -8,3 +10,27 @@ import (
func UUID() string {
return uuid.NewV4().String()
}
// Returns true if the string looks like a standard UUID.
func IsUUID(s string) bool {
return len(s) == 36 && IsHex(s)
}
// SanitizeUUID normalizes UUIDs found in XMP or Exif metadata.
func SanitizeUUID(s string) string {
if s == "" {
return ""
}
s = strings.Replace(strings.TrimSpace(s), "\"", "", -1)
if start := strings.LastIndex(s, ":"); start != -1 {
s = s[start+1:]
}
if !IsUUID(s) {
return ""
}
return strings.ToLower(s)
}

39
pkg/rnd/uuid_test.go Normal file
View File

@@ -0,0 +1,39 @@
package rnd
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestUUID(t *testing.T) {
for n := 0; n < 5; n++ {
uuid := UUID()
t.Logf("token: %s", uuid)
assert.Equal(t, 36, len(uuid))
}
}
func BenchmarkUUID(b *testing.B) {
for n := 0; n < b.N; n++ {
UUID()
}
}
func TestIsUUID(t *testing.T) {
assert.True(t, IsUUID("dafbfeb8-a129-4e7c-9cf0-e7996a701cdb"))
assert.True(t, IsUUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
assert.False(t, IsUUID("55785BAC-9H4B-4747-B090-EE123FFEE437"))
assert.True(t, IsUUID("550e8400-e29b-11d4-a716-446655440000"))
assert.False(t, IsUUID("4B1FEF2D1CF4A5BE38B263E0637EDEAD"))
}
func TestSanitizeUUID(t *testing.T) {
assert.Equal(t, "dafbfeb8-a129-4e7c-9cf0-e7996a701cdb", SanitizeUUID(" \"dafbfeb8-a129-4e7c-9cf0-e7996a701cdb\" "))
assert.Equal(t, "dafbfeb8-a129-4e7c-9cf0-e7996a701cdb", SanitizeUUID(" xmp:dafbfeb8-a129-4e7c-9cf0-e7996a701cdb "))
assert.Equal(t, "dafbfeb8-a129-4e7c-9cf0-e7996a701cdb", SanitizeUUID("dafbfeb8-a129-4e7c-9cf0-e7996a701cdb"))
assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c8", SanitizeUUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
assert.Equal(t, "", SanitizeUUID("55785BAC-9H4B-4747-B090-EE123FFEE437"))
assert.Equal(t, "550e8400-e29b-11d4-a716-446655440000", SanitizeUUID("550e8400-e29b-11d4-a716-446655440000"))
assert.Equal(t, "", SanitizeUUID("4B1FEF2D1CF4A5BE38B263E0637EDEAD"))
}