From 70afd7c74265dd0a748a14a5971a791efd60ed9c Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Fri, 13 Sep 2024 08:50:27 -0600 Subject: [PATCH] Support items with auth:schemes --- extensions/auth/auth.go | 25 ++++++ extensions/auth/auth_test.go | 164 +++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) diff --git a/extensions/auth/auth.go b/extensions/auth/auth.go index 992abbd..79eed19 100644 --- a/extensions/auth/auth.go +++ b/extensions/auth/auth.go @@ -18,12 +18,37 @@ const ( func init() { r := regexp.MustCompile(extensionPattern) + stac.RegisterItemExtension(r, func() stac.Extension { return &Item{} }) stac.RegisterCollectionExtension(r, func() stac.Extension { return &Collection{} }) stac.RegisterCatalogExtension(r, func() stac.Extension { return &Catalog{} }) stac.RegisterAssetExtension(r, func() stac.Extension { return &Asset{} }) stac.RegisterLinkExtension(r, func() stac.Extension { return &Link{} }) } +type Item struct { + Schemes map[string]*Scheme `json:"auth:schemes,omitempty"` +} + +var _ stac.Extension = (*Item)(nil) + +func (*Item) URI() string { + return extensionUri +} + +func (e *Item) Encode(itemMap map[string]any) error { + return stac.EncodeExtendedItemProperties(e, itemMap) +} + +func (e *Item) Decode(itemMap map[string]any) error { + if err := stac.DecodeExtendedItemProperties(e, itemMap); err != nil { + return err + } + if e.Schemes == nil { + return stac.ErrExtensionDoesNotApply + } + return nil +} + type Collection struct { Schemes map[string]*Scheme } diff --git a/extensions/auth/auth_test.go b/extensions/auth/auth_test.go index b073294..f0597d3 100644 --- a/extensions/auth/auth_test.go +++ b/extensions/auth/auth_test.go @@ -10,6 +10,88 @@ import ( "github.com/stretchr/testify/require" ) +func TestItemExtendedMarshal(t *testing.T) { + item := &stac.Item{ + Version: "1.0.0", + Id: "item-id", + Geometry: map[string]any{ + "type": "Point", + "coordinates": []float64{0, 0}, + }, + Properties: map[string]any{ + "test": "value", + }, + Links: []*stac.Link{ + {Href: "https://example.com/stac/item-id", Rel: "self"}, + }, + Assets: map[string]*stac.Asset{ + "image": { + Title: "Image", + Href: "https://example.com/stac/item-id/image.tif", + Type: "image/tif", + Extensions: []stac.Extension{ + &auth.Asset{ + Refs: []string{"openid"}, + }, + }, + }, + }, + Extensions: []stac.Extension{ + &auth.Item{ + Schemes: map[string]*auth.Scheme{ + "openid": { + Type: "openIdConnect", + Description: "Test auth configuration", + OpenIdConnectUrl: "https://example.com/auth/.well-known/openid-configuration", + }, + }, + }, + }, + } + + data, err := json.Marshal(item) + require.NoError(t, err) + + expected := `{ + "type": "Feature", + "stac_version": "1.0.0", + "id": "item-id", + "geometry": { + "type": "Point", + "coordinates": [0, 0] + }, + "properties": { + "test": "value", + "auth:schemes": { + "openid": { + "type": "openIdConnect", + "description": "Test auth configuration", + "openIdConnectUrl": "https://example.com/auth/.well-known/openid-configuration" + } + } + }, + "links": [ + { + "rel": "self", + "href": "https://example.com/stac/item-id" + } + ], + "assets": { + "image": { + "title": "Image", + "href": "https://example.com/stac/item-id/image.tif", + "type": "image/tif", + "auth:refs": ["openid"] + } + }, + "stac_extensions": [ + "https://stac-extensions.github.io/authentication/v1.1.0/schema.json" + ] + }` + + assert.JSONEq(t, expected, string(data)) +} + func TestCollectionExtendedMarshal(t *testing.T) { collection := &stac.Collection{ Version: "1.0.0", @@ -150,6 +232,88 @@ func TestCollectionLinkExtendedMarshal(t *testing.T) { assert.JSONEq(t, expected, string(data)) } +func TestItemExtendedUnmarshal(t *testing.T) { + data := []byte(`{ + "type": "Feature", + "stac_version": "1.0.0", + "id": "item-id", + "geometry": { + "type": "Point", + "coordinates": [0, 0] + }, + "properties": { + "test": "value", + "auth:schemes": { + "openid": { + "type": "openIdConnect", + "description": "Test auth configuration", + "openIdConnectUrl": "https://example.com/auth/.well-known/openid-configuration" + } + } + }, + "links": [ + { + "rel": "self", + "href": "https://example.com/stac/item-id" + } + ], + "assets": { + "image": { + "title": "Image", + "href": "https://example.com/stac/item-id/image.tif", + "type": "image/tif", + "auth:refs": ["openid"] + } + }, + "stac_extensions": [ + "https://stac-extensions.github.io/authentication/v1.1.0/schema.json" + ] + }`) + + item := &stac.Item{} + require.NoError(t, json.Unmarshal(data, item)) + + expected := &stac.Item{ + Version: "1.0.0", + Id: "item-id", + Geometry: map[string]any{ + "type": "Point", + "coordinates": []any{float64(0), float64(0)}, + }, + Properties: map[string]any{ + "test": "value", + }, + Links: []*stac.Link{ + {Href: "https://example.com/stac/item-id", Rel: "self"}, + }, + Assets: map[string]*stac.Asset{ + "image": { + Title: "Image", + Href: "https://example.com/stac/item-id/image.tif", + Type: "image/tif", + Extensions: []stac.Extension{ + &auth.Asset{ + Refs: []string{"openid"}, + }, + }, + }, + }, + Extensions: []stac.Extension{ + &auth.Item{ + Schemes: map[string]*auth.Scheme{ + "openid": { + Type: "openIdConnect", + Description: "Test auth configuration", + OpenIdConnectUrl: "https://example.com/auth/.well-known/openid-configuration", + }, + }, + }, + }, + } + + assert.Equal(t, expected, item) +} + func TestCollectionExtendedUnmarshal(t *testing.T) { data := []byte(`{ "type": "Collection",