Skip to content

Commit

Permalink
CMR-3858 Update Catalog Item ACL endpoints to accept concept_id (#82)
Browse files Browse the repository at this point in the history
* CMR-3858 adds concept-ids to catalog item acls

* CMR-3858 fixes db migration where clause

* CMR-3858 fixes db migration

* CMR-3858 fixes alignment

* CMR-3858 fixes db migration

* CMR-3858 adds some tests, corrects schema

* CMR-3858 adds more test coverage

* CMR-3858 adds more test coverage

* CMR-3858 lauren's pr comments

* CMR-3858 simplifies regex in validation, simplifies doseq in event handler

* CMR-3858 santizes entry titles

* CMR-3858 santizes entry titles

* CMR-3858 adds doc string

* CMR-3858 converting added tests to are3

* CMR-3858 converting added tests to are3
  • Loading branch information
daniel-zamora authored May 26, 2017
1 parent 83e9eb4 commit 8c2a496
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 11 deletions.
4 changes: 4 additions & 0 deletions access-control-app/docs/acl-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ Properties of the `CollectionIdentifierType` object:

The object is an array with all elements of the type `string`.

#### `concept-ids` (array)

The object is an array with all elements of the type `string`.

#### `access_value` (AccessValueType)

#### `temporal` (TemporalIdentifierType)
Expand Down
2 changes: 1 addition & 1 deletion access-control-app/docs/acl-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Unlike the other types of resource identities, catalog item identities contain a
- **provider_id**: The provider with which the identity is associated
- **collection_applicable**: Flag indicating whether the filter matches collections
- **granule_applicable**: Flag indicating whether the filter matches granules
- **collection_identifier**: A filter defining the collections matched by this ACL. This filter consists of a combination of Collection Entry Titles, a restriction flag(AKA Access Value) range, and a temporal range (see the [schema](acl-schema.html#-collectionidentifiertype-object-))
- **collection_identifier**: A filter defining the collections matched by this ACL. This filter consists of a combination of Collection Entry Titles, Collection Concept Ids, a restriction flag(AKA Access Value) range, and a temporal range (see the [schema](acl-schema.html#-collectionidentifiertype-object-))
- **granule_identifier**: A filter defining the granules matched by this ACL. This filter consists of a combination of restriction flag (AKA Access Value) range, and a temporal range and can be combined with a collection_identifier (see the [schema](acl-schema.html#-granuleidentifiertype-object-))

It should be noted that while temporal Catalog item filters are supported by the API, they are not currently used operationally. In addition, a restriction flag (or Access Value) filter may specify a include_undefined_value flag. If set to false, only items which have an access value within the specified range will be matched. If set to true, item with no value set, as well as those with a value in the specified range will be matched. include_undefined_value defaults to 'false'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
:granule-identifier m/bool-field-mapping
:granule-applicable m/bool-field-mapping

:concept-ids m/string-field-mapping
:entry-title m/string-field-mapping

:collection-access-value-min m/int-field-mapping
Expand Down Expand Up @@ -316,6 +317,12 @@
(when-let [entry-titles (get-in acl [:catalog-item-identity :collection-identifier :entry-titles])]
{:entry-title entry-titles}))

(defn- concept-ids-elastic-doc-map
"Returns map for entry titles to be merged into full elastic doc"
[acl]
(when-let [concept-ids (get-in acl [:catalog-item-identity :collection-identifier :concept-ids])]
{:concept-ids concept-ids}))

(defn acl-concept-map->elastic-doc
"Converts a concept map containing an acl into the elasticsearch document to index."
[concept-map]
Expand All @@ -334,6 +341,7 @@
(access-value-elastic-doc-map acl)
(temporal-elastic-doc-map acl)
(entry-title-elastic-doc-map acl)
(concept-ids-elastic-doc-map acl)
(identifier-applicable-elastic-doc-map acl)
(assoc (select-keys concept-map [:concept-id :revision-id])
:display-name display-name
Expand Down
2 changes: 2 additions & 0 deletions access-control-app/src/cmr/access_control/data/acl_schema.clj
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@
:properties {:entry_titles {:type :array
:items {:type :string
:minLength 1}}
:concept_ids {:type :array
:items (ref-def :IdentifierType)}
:access_value (ref-def :AccessValueType)
:temporal (ref-def :TemporalIdentifierType)}}
:GranuleIdentifierType {:type :object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[cmr.acl.core :as acl]
[cmr.common.date-time-parser :as dtp]
[cmr.common.validations.core :as v]
[cmr.common.concepts :as concepts]
[cmr.transmit.metadata-db :as mdb1]
[cmr.transmit.metadata-db2 :as mdb]))

Expand Down Expand Up @@ -93,6 +94,18 @@
(when-not (seq (mdb1/find-concepts context {:provider-id provider-id :entry-title entry-title} :collection))
{key-path [(format "collection with entry-title [%s] does not exist in provider [%s]" entry-title provider-id)]})))))

(defn- make-collection-concept-ids-validations
"Returns a validation for the concept_ids part of a collection identifier, closed over the context and ACL to be validated."
[context acl]
(let [provider-id (-> acl :catalog-item-identity :provider-id)]
[(v/every (fn [key-path concept-id]
(let [regex #"C\d+-\S+"]
(when-not (re-matches regex concept-id)
{key-path [(format "[%s] is not a valid collection concept-id." concept-id)]}))))
(v/every (fn [key-path concept-id]
(when-not (seq (mdb1/find-concepts context {:provider-id provider-id :concept-id concept-id} :collection))
{key-path [(format "collection with concept-id [%s] does not exist in provider [%s]" concept-id provider-id)]})))]))

(defn- access-value-validation
"Validates the access_value part of a collection or granule identifier."
[key-path access-value-map]
Expand Down Expand Up @@ -121,6 +134,7 @@
"Returns a validation for an ACL catalog_item_identity.collection_identifier closed over the given context and ACL to be validated."
[context acl]
{:entry-titles (v/when-present (make-collection-entry-titles-validation context acl))
:concept-ids (v/when-present (make-collection-concept-ids-validations context acl))
:access-value (v/when-present [access-value-validation access-value-min-max-value-validation])
:temporal (v/when-present temporal-identifier-validation)})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,26 @@
(defmethod handle-indexing-event [:concept-delete :collection]
[context {:keys [concept-id revision-id]}]
(let [concept-map (mdb/get-concept context concept-id revision-id)
collection-concept (acl-matchers/add-acl-enforcement-fields-to-concept concept-map)
entry-title (:EntryTitle collection-concept)]
(doseq [acl-concept (acl-service/get-all-acl-concepts context)
collection-concept (acl-matchers/add-acl-enforcement-fields-to-concept concept-map)]
(doseq [key-path [:entry-titles :concept-ids]
acl-concept (acl-service/get-all-acl-concepts context)
:let [parsed-acl (acl-service/get-parsed-acl acl-concept)
catalog-item-id (:catalog-item-identity parsed-acl)
acl-entry-titles (:entry-titles (:collection-identifier catalog-item-id))]
value (if (= key-path :entry-titles)
(:EntryTitle collection-concept)
(:concept-id collection-concept))
acl-values (get (:collection-identifier catalog-item-id) key-path)]
:when (and (= (:provider-id collection-concept) (:provider-id catalog-item-id))
(some #{entry-title} acl-entry-titles))]
(if (= 1 (count acl-entry-titles))
;; the ACL only references the collection being deleted, and therefore the ACL should be deleted
(some #{value} acl-values))]
(if (= 1 (count acl-values))
;; The ACL only references the collection being deleted, and therefore the ACL should be deleted.
;; With the addition of concept-ids, this assumes entry-titles and concept-ids are in sync.
(acl-service/delete-acl (transmit-config/with-echo-system-token context)
(:concept-id acl-concept))
;; otherwise the ACL references other collections, and will be updated
;; Otherwise the ACL references other collections, and will be updated
(let [new-acl (update-in parsed-acl
[:catalog-item-identity :collection-identifier :entry-titles]
#(remove #{entry-title} %))]
[:catalog-item-identity :collection-identifier key-path]
#(remove #{value} %))]
(acl-service/update-acl (transmit-config/with-echo-system-token context)
(:concept-id acl-concept) new-acl))))))

Expand Down

0 comments on commit 8c2a496

Please sign in to comment.