hydramata-works 0.0.1.prerelease
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.hound.yml +818 -0
- data/.rspec +2 -0
- data/.travis.yml +20 -0
- data/CONTRIBUTING.md +220 -0
- data/Gemfile +36 -0
- data/Guardfile +36 -0
- data/LICENSE +15 -0
- data/README.md +36 -0
- data/Rakefile +47 -0
- data/TODO.md +74 -0
- data/VISION.md +19 -0
- data/app/forms/hydramata/works/entity_form.rb +92 -0
- data/app/forms/hydramata/works/validation_service.rb +78 -0
- data/app/models/hydramata/works/data_definition.rb +57 -0
- data/app/models/hydramata/works/entities.rb +11 -0
- data/app/models/hydramata/works/entity.rb +75 -0
- data/app/models/hydramata/works/predicate.rb +35 -0
- data/app/models/hydramata/works/predicate_presentation_sequences/storage.rb +29 -0
- data/app/models/hydramata/works/predicate_set.rb +44 -0
- data/app/models/hydramata/works/predicate_sets/storage.rb +45 -0
- data/app/models/hydramata/works/predicates.rb +14 -0
- data/app/models/hydramata/works/predicates/storage.rb +33 -0
- data/app/models/hydramata/works/presentation_structure.rb +29 -0
- data/app/models/hydramata/works/property.rb +72 -0
- data/app/models/hydramata/works/property_set.rb +89 -0
- data/app/models/hydramata/works/validations.rb +6 -0
- data/app/models/hydramata/works/value.rb +34 -0
- data/app/models/hydramata/works/work_type.rb +49 -0
- data/app/models/hydramata/works/work_types.rb +14 -0
- data/app/models/hydramata/works/work_types/storage.rb +42 -0
- data/app/parsers/hydramata/works/datastream_parser.rb +36 -0
- data/app/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser.rb +60 -0
- data/app/parsers/hydramata/works/datastream_parsers/simple_xml_parser.rb +27 -0
- data/app/parsers/hydramata/works/predicate_parser.rb +31 -0
- data/app/parsers/hydramata/works/predicate_parsers/simple_parser.rb +13 -0
- data/app/parsers/hydramata/works/validations_parser.rb +22 -0
- data/app/parsers/hydramata/works/value_parser.rb +26 -0
- data/app/parsers/hydramata/works/value_parsers.rb +27 -0
- data/app/parsers/hydramata/works/value_parsers/date_parser.rb +13 -0
- data/app/parsers/hydramata/works/value_parsers/interrogation_parser.rb +18 -0
- data/app/parsers/hydramata/works/value_parsers/simple_parser.rb +14 -0
- data/app/presenters/hydramata/works/base_presenter.rb +146 -0
- data/app/presenters/hydramata/works/dom_attributes_builder.rb +24 -0
- data/app/presenters/hydramata/works/entity_presenter.rb +67 -0
- data/app/presenters/hydramata/works/fieldset_presenter.rb +54 -0
- data/app/presenters/hydramata/works/property_presenter.rb +51 -0
- data/app/presenters/hydramata/works/value_presenter.rb +60 -0
- data/app/renderers/hydramata/works/entity_renderer.rb +45 -0
- data/app/views/hydramata/works/fieldsets/_edit.html.erb +4 -0
- data/app/views/hydramata/works/fieldsets/_show.html.erb +8 -0
- data/app/views/hydramata/works/fieldsets/_show.json.jbuilder +8 -0
- data/app/views/hydramata/works/properties/_edit.html.erb +12 -0
- data/app/views/hydramata/works/properties/_show.html.erb +3 -0
- data/app/views/hydramata/works/properties/_show.json.jbuilder +1 -0
- data/app/views/hydramata/works/works/_edit.html.erb +8 -0
- data/app/views/hydramata/works/works/_new.html.erb +8 -0
- data/app/views/hydramata/works/works/_show.html.erb +3 -0
- data/app/views/hydramata/works/works/_show.json.jbuilder +13 -0
- data/app/wranglers/hydramata/works/fedora_wrangler.rb +66 -0
- data/bin/rails +12 -0
- data/db/migrate/20140606132349_create_hydramata_work_predicates.rb +13 -0
- data/db/migrate/20140606132350_create_hydramata_work_types.rb +9 -0
- data/db/migrate/20140606132351_create_hydramata_work_predicate_sets.rb +13 -0
- data/db/migrate/20140606132352_create_hydramata_work_predicate_presentation_sequences.rb +12 -0
- data/db/migrate/20140623200635_add_validations_to_predicates.rb +5 -0
- data/db/migrate/20140627134133_adding_item_type_schema_dot_org_to_work_type.rb +5 -0
- data/db/migrate/20140627140840_adding_item_prop_schema_dot_org_to_predicate.rb +5 -0
- data/db/seeds.rb +36 -0
- data/documents/administrative-set-strawperson.md +45 -0
- data/documents/diagrams/hydramata-refactor-tasks.dot +88 -0
- data/documents/diagrams/hydramata-sip-dip-aip.dot +88 -0
- data/documents/diagrams/hydramata-work-architecture.dot +129 -0
- data/documents/diagrams/hydramata-work-subcomponents.dot +36 -0
- data/documents/diagrams/map-from-database-to-work-object.dot +44 -0
- data/documents/diagrams/map-from-fedora-to-work-object.dot +51 -0
- data/documents/diagrams/map-from-input-to-work-object.dot +37 -0
- data/documents/diagrams/map-from-work-object-to-database.dot +31 -0
- data/documents/diagrams/work-rendering.dot +53 -0
- data/documents/diagrams/work-structure.dot +32 -0
- data/documents/handling-work.md +224 -0
- data/documents/high-level-stories.md +105 -0
- data/documents/hydramata-components.md +82 -0
- data/documents/interface-between-work-and-permissions.md +131 -0
- data/documents/interface-between-work-and-workflow.md +6 -0
- data/documents/timeline.md +75 -0
- data/fs +3 -0
- data/gemfiles/rails4.1.gemfile +12 -0
- data/gemfiles/rails4.gemfile +13 -0
- data/hydramata-works.gemspec +43 -0
- data/lib/hydramata-works.rb +23 -0
- data/lib/hydramata/works/conversions.rb +21 -0
- data/lib/hydramata/works/conversions/exceptions.rb +18 -0
- data/lib/hydramata/works/conversions/predicate.rb +22 -0
- data/lib/hydramata/works/conversions/predicate_set.rb +28 -0
- data/lib/hydramata/works/conversions/presented_fieldsets.rb +28 -0
- data/lib/hydramata/works/conversions/presenter.rb +13 -0
- data/lib/hydramata/works/conversions/property.rb +31 -0
- data/lib/hydramata/works/conversions/property_set.rb +23 -0
- data/lib/hydramata/works/conversions/translation_key_fragment.rb +20 -0
- data/lib/hydramata/works/conversions/value.rb +20 -0
- data/lib/hydramata/works/conversions/work_type.rb +26 -0
- data/lib/hydramata/works/engine.rb +31 -0
- data/lib/hydramata/works/linters.rb +99 -0
- data/lib/hydramata/works/linters/implement_data_definition_interface_matcher.rb +17 -0
- data/lib/hydramata/works/linters/implement_entity_interface_matcher.rb +16 -0
- data/lib/hydramata/works/linters/implement_predicate_interface_matcher.rb +17 -0
- data/lib/hydramata/works/linters/implement_predicate_set_interface_matcher.rb +8 -0
- data/lib/hydramata/works/linters/implement_property_set_interface_matcher.rb +8 -0
- data/lib/hydramata/works/linters/implement_value_interface_matcher.rb +8 -0
- data/lib/hydramata/works/linters/implement_work_type_interface_matcher.rb +13 -0
- data/lib/hydramata/works/linters/interface_matcher_builder.rb +36 -0
- data/lib/hydramata/works/translator.rb +67 -0
- data/lib/hydramata/works/version.rb +5 -0
- data/lib/hydramata_works.rb +2 -0
- data/lib/tasks/hydramata_work_tasks.rake +4 -0
- data/run_each_spec_in_isolation +16 -0
- data/run_each_spec_in_isolation.txt +110 -0
- data/script/analyzer.rb +124 -0
- data/script/fast_specs +22 -0
- data/spec/features/fedora_to_in_memory_spec.rb +60 -0
- data/spec/features/format_and_view_path_overrides_spec.rb +72 -0
- data/spec/features/in_memory_to_output_buffer_spec.rb +109 -0
- data/spec/features/instantiate_entity_from_persisted_work_type_spec.rb +26 -0
- data/spec/features/new_user_input_to_in_memory_spec.rb +75 -0
- data/spec/features/translation_services_spec.rb +107 -0
- data/spec/features/validate_entity_based_on_work_type_structure_spec.rb +19 -0
- data/spec/fixtures/cassettes/fedora-object.yml +299 -0
- data/spec/fixtures/translations.yml +20 -0
- data/spec/forms/hydramata/works/entity_form_spec.rb +83 -0
- data/spec/forms/hydramata/works/validation_service_spec.rb +32 -0
- data/spec/lib/hydramata-work_spec.rb +14 -0
- data/spec/lib/hydramata/works/conversions/predicate_set_spec.rb +50 -0
- data/spec/lib/hydramata/works/conversions/predicate_spec.rb +43 -0
- data/spec/lib/hydramata/works/conversions/presented_fieldsets_spec.rb +52 -0
- data/spec/lib/hydramata/works/conversions/presenter_spec.rb +22 -0
- data/spec/lib/hydramata/works/conversions/property_set_spec.rb +42 -0
- data/spec/lib/hydramata/works/conversions/property_spec.rb +68 -0
- data/spec/lib/hydramata/works/conversions/translation_key_fragment_spec.rb +45 -0
- data/spec/lib/hydramata/works/conversions/value_spec.rb +36 -0
- data/spec/lib/hydramata/works/conversions/work_type_spec.rb +55 -0
- data/spec/lib/hydramata/works/translator_spec.rb +81 -0
- data/spec/models/hydramata/works/data_definition_spec.rb +53 -0
- data/spec/models/hydramata/works/entity_spec.rb +50 -0
- data/spec/models/hydramata/works/predicate_presentation_sequences/storage_spec.rb +15 -0
- data/spec/models/hydramata/works/predicate_set_spec.rb +63 -0
- data/spec/models/hydramata/works/predicate_sets/storage_spec.rb +37 -0
- data/spec/models/hydramata/works/predicate_spec.rb +16 -0
- data/spec/models/hydramata/works/predicates/storage_spec.rb +78 -0
- data/spec/models/hydramata/works/predicates_spec.rb +18 -0
- data/spec/models/hydramata/works/presentation_structure_spec.rb +27 -0
- data/spec/models/hydramata/works/property_set_spec.rb +135 -0
- data/spec/models/hydramata/works/property_spec.rb +74 -0
- data/spec/models/hydramata/works/value_spec.rb +61 -0
- data/spec/models/hydramata/works/work_type_spec.rb +45 -0
- data/spec/models/hydramata/works/work_types/storage_spec.rb +74 -0
- data/spec/models/hydramata/works/work_types_spec.rb +16 -0
- data/spec/parsers/hydramata/works/datastream_parser_spec.rb +29 -0
- data/spec/parsers/hydramata/works/datastream_parsers/rdf_ntriples_parser_spec.rb +65 -0
- data/spec/parsers/hydramata/works/datastream_parsers/simple_xml_parser_spec.rb +37 -0
- data/spec/parsers/hydramata/works/predicate_parser_spec.rb +30 -0
- data/spec/parsers/hydramata/works/predicate_parsers/simple_parser_spec.rb +20 -0
- data/spec/parsers/hydramata/works/validations_parser_spec.rb +31 -0
- data/spec/parsers/hydramata/works/value_parser_spec.rb +22 -0
- data/spec/parsers/hydramata/works/value_parsers/simple_parser_spec.rb +20 -0
- data/spec/parsers/hydramata/works/value_parsers_spec.rb +36 -0
- data/spec/presenters/hydramata/works/base_presenter_spec.rb +111 -0
- data/spec/presenters/hydramata/works/dom_attributes_builder_spec.rb +26 -0
- data/spec/presenters/hydramata/works/entity_presenter_spec.rb +51 -0
- data/spec/presenters/hydramata/works/fieldset_presenter_spec.rb +58 -0
- data/spec/presenters/hydramata/works/property_presenter_spec.rb +42 -0
- data/spec/presenters/hydramata/works/value_presenter_spec.rb +49 -0
- data/spec/renderers/hydramata/works/entity_renderer_spec.rb +25 -0
- data/spec/spec_active_record_helper.rb +30 -0
- data/spec/spec_fast_helper.rb +12 -0
- data/spec/spec_slow_helper.rb +56 -0
- data/spec/spec_view_helper.rb +14 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +21 -0
- data/spec/views/hydramata/works/fieldsets/_edit.html.erb_spec.rb +29 -0
- data/spec/views/hydramata/works/fieldsets/_show.html.erb_spec.rb +25 -0
- data/spec/views/hydramata/works/properties/_edit.html.erb_spec.rb +22 -0
- data/spec/views/hydramata/works/properties/_show.html.erb_spec.rb +22 -0
- data/spec/views/hydramata/works/works/_edit.html.erb_spec.rb +23 -0
- data/spec/views/hydramata/works/works/_new.html.erb_spec.rb +23 -0
- data/spec/views/hydramata/works/works/_show.html.erb_spec.rb +24 -0
- data/spec/wranglers/hydramata/works/fedora_wrangler_spec.rb +26 -0
- metadata +466 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
# Hydramata Components
|
2
|
+
|
3
|
+
In terms of dependencies, the Work component should happen first.
|
4
|
+
Then the Permissions and Workflow components can happen independently.
|
5
|
+
|
6
|
+
We can begin working on Permissions and Workflow as the Work component is in process.
|
7
|
+
Permissions will be easier to do in isolation whereas Workflow will require greater coordination with the Work component effort.
|
8
|
+
|
9
|
+
Once the Work, Permissions, and Workflow components are complete, most other components could proceed.
|
10
|
+
|
11
|
+
## Hydramata::Works
|
12
|
+
|
13
|
+
A way to suggest the properties and structure of different work types (ie Article, Dataset, etc) while allowing the persisted work to be the authority of its properties.
|
14
|
+
|
15
|
+
Responsible for defining how a work is:
|
16
|
+
|
17
|
+
* Represented at three different levels (ie Persistence, Application Object, and User Output).
|
18
|
+
* Transformed from one level to another (ie Persistence -> Application Object; Application Object -> User Output).
|
19
|
+
|
20
|
+
### What pain points is Hydramata::Works addressing?
|
21
|
+
|
22
|
+
* Remove duplication of knowledge of a work's data and structure.
|
23
|
+
Presently knowledge of a work's data is in the ActiveFedora model, datastreams, show page, and edit page.
|
24
|
+
* Allow institutions to define their own work types.
|
25
|
+
* Improve the sharability of components that interact with a well-defined narrow interface for a work.
|
26
|
+
* Allow institutions to add new work types without requiring deploys.
|
27
|
+
* Allow institutions to modify existing work types without always requiring data migrations.
|
28
|
+
* Acknowledge that our understanding of the suggested structure and properties of a work is changing over time, but this shouldn't mandate a migration.
|
29
|
+
|
30
|
+
## Hydramata::Permissions
|
31
|
+
|
32
|
+
A common interface for application level permissions. That is to say "Can I view this work?" or perhaps more specifically, "When I view this work, what do I see?"
|
33
|
+
|
34
|
+
Responsible for defining what an agent interacting with the application can do.
|
35
|
+
|
36
|
+
The scope of the permissions system is beyond just works.
|
37
|
+
Can this person, because they are a member of these groups take this specific action.
|
38
|
+
And the action could be:
|
39
|
+
|
40
|
+
* "Show the Resque worker queue."
|
41
|
+
* "Masquerade as another user."
|
42
|
+
* "Edit a given work."
|
43
|
+
|
44
|
+
### What pain points is Hydramata::Permissions addressing?
|
45
|
+
|
46
|
+
* Normalize the application permissions (i.e. Repository Manager and System Manager are handled differently from a Work's editor)
|
47
|
+
* Expose a well-defined narrow interface for Groups, so that each institution could create an adaptor that suits them.
|
48
|
+
* Allow institutions to add new roles to represent a set of abilities (ie a "Librarian" role could edit all AIPs)
|
49
|
+
|
50
|
+
## Hydramata::Worksflow
|
51
|
+
|
52
|
+
A common processing architecture for running tasks that need not be run within a request cycle.
|
53
|
+
|
54
|
+
Responsible for providing a asynchronous processing capabilities.
|
55
|
+
This could be ingesting SIPs, sending emails to depositors, running characterizations, and generating derivatives.
|
56
|
+
|
57
|
+
### What pain points is Hydramata::Permissions addressing?
|
58
|
+
|
59
|
+
* Acknowledging the fragility of deposit when handled within request queue ([See Google Doc](https://docs.google.com/document/d/1AyEFK0PTIt4STFcsNw2x5zeJthP0rRxKX7K0Yv5O_hM/edit)).
|
60
|
+
* Acknowledging the transactional challenges of coordinating updates to Fedora and SOLR so as to deliver on the promise of preservation.
|
61
|
+
* Teasing apart numerous small tasks that can be run and tested in isolation.
|
62
|
+
* Speeding up the responsiveness and scalability of user deposit.
|
63
|
+
|
64
|
+
## Hydramata::AdministrativeSet
|
65
|
+
|
66
|
+
A conceptual place where Works are put.
|
67
|
+
|
68
|
+
As it relates to the Hydramata::Permissions component, the AdministrativeSet is a Resource.
|
69
|
+
An AdministrativeSetMembership is also a Resource.
|
70
|
+
|
71
|
+
If I want to create a Work, I need to declare which AdministrativeSet I want to put it in.
|
72
|
+
"Can I create AdministrativeSetMembership (an Article in this AdministrativeSet)?"
|
73
|
+
|
74
|
+
### @TODO
|
75
|
+
|
76
|
+
Consider how we persist a Work's AdministrativeSet.
|
77
|
+
Is this uneditable?
|
78
|
+
Is the attribute shown on the page?
|
79
|
+
How to enforce that?
|
80
|
+
|
81
|
+
The reification strategy.
|
82
|
+
If a property is present but not editable, discard any value associated with the property when we attempt to.
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# DRAFT - Interface between Work and Permissions component - DRAFT
|
2
|
+
|
3
|
+
## Initial Interface
|
4
|
+
|
5
|
+
For a Work to assert its available predicates, the Permissions subsystem should:
|
6
|
+
|
7
|
+
* Provide a `Hydramata::Permissions.roles_for(agent)` service. Responsible for getting all of the roles of an agent.
|
8
|
+
* Each of the returned objects from `Hydramata::Permissions.roles_for` should:
|
9
|
+
* have a unique identifying symbol from which the Work subsystem can craft the appropriate Work Reification Strategy (which properties go on the work value object that is being passed through the system).
|
10
|
+
|
11
|
+
The Permissions subsystem is concerned with these three concepts:
|
12
|
+
|
13
|
+
* Resource - exposes the following methods `#persisted?`, `#to_key`, `#class#model_name` (a subset of the [ActiveModel::Lint::Test](http://api.rubyonrails.org/classes/ActiveModel/Lint/Tests.html))
|
14
|
+
* Action - what is the agent trying to do with the resource? This would likely be the Controller#action_name
|
15
|
+
* Agent - who (or what) is attempting to take action on the resource
|
16
|
+
|
17
|
+
For the Permissions subsystem to interact with a Work, the Work object should implement a Resource interface.
|
18
|
+
|
19
|
+
### Searching for Resources
|
20
|
+
|
21
|
+
This is a more complicated case. When searching for Works there are two permission checks:
|
22
|
+
|
23
|
+
1. "Can I create a Search?" - In other words, can I perform a search?
|
24
|
+
1. "Can I show a given Search result?" - In other words, what are the documents returned in the search?
|
25
|
+
|
26
|
+
The Permission system is responsible for appending additional restrictions to Search object/query.
|
27
|
+
The additional restrictions would modify the Search by in effect adding "AND I can Show" to the search query.
|
28
|
+
|
29
|
+
For a search request, we will search across all indexed properties of the solr documents, regardless of permissions.
|
30
|
+
When we render a search result document, only properties that the user can access will be available for rendering to the output buffer.
|
31
|
+
|
32
|
+
Said another way:
|
33
|
+
|
34
|
+
```gherkin
|
35
|
+
Feature: I can search amongst properties that I may not be able to access
|
36
|
+
As patron of the library
|
37
|
+
I want to...
|
38
|
+
So that I...
|
39
|
+
|
40
|
+
Scenario:
|
41
|
+
Given an Agent
|
42
|
+
And there exists the following indexed Works:
|
43
|
+
| work_type | properties |
|
44
|
+
| Article | { title: 'Hello', secret: 'Dog' } |
|
45
|
+
| Book | { title: 'Dog' } |
|
46
|
+
| Article | { title: 'World' } |
|
47
|
+
And I can accessess the following predicates by Work Type:
|
48
|
+
| work_type | predicates |
|
49
|
+
| Article | [:title] |
|
50
|
+
| Book | [:title] |
|
51
|
+
When the Agent searches for "Dog"
|
52
|
+
Then they will find two Works with the following properties:
|
53
|
+
| work_type | properties |
|
54
|
+
| Article | { title: 'Hello' } |
|
55
|
+
| Book | { title: 'Dog' } |
|
56
|
+
```
|
57
|
+
|
58
|
+
## Initial Scenarios
|
59
|
+
|
60
|
+
```gherkin
|
61
|
+
Feature: Role-based access to Predicates
|
62
|
+
As the steward of repository content
|
63
|
+
I want to ensure that the appropriate content is available based on the requesting Agent.
|
64
|
+
And that some content is not available.
|
65
|
+
So that I am upholding any institutional policies and protocols regarding content.
|
66
|
+
|
67
|
+
As the Work component is responsible for wrangling the Work from persistence to memory to output buffer,
|
68
|
+
it would be the responsibility of the Work component to negotiate any predicate level access.
|
69
|
+
|
70
|
+
Scenario Outline:
|
71
|
+
|
72
|
+
Given an Agent with role <role>
|
73
|
+
And a Work of work type <work_type> with predicates <predicates>
|
74
|
+
And the role <role> can only access the following predicates <accessible_predicates>
|
75
|
+
When the Agent requests the Work
|
76
|
+
Then the Work asserts that the Agent only accesses the following predicates <accessible_predicates>
|
77
|
+
|
78
|
+
Examples:
|
79
|
+
| role | work_type | predicates | accessible_predicates |
|
80
|
+
| Anonymous | Article | :identifier, :title | :identifier |
|
81
|
+
| Librarian | Article | :identifier, :title | :identifier, :title |
|
82
|
+
| Librarian | Article | :identifier, :title | :identifier, :title |
|
83
|
+
```
|
84
|
+
|
85
|
+
```gherkin
|
86
|
+
Feature: Work object interacting with Permissions
|
87
|
+
As the steward of repository content
|
88
|
+
I want to ensure that the appropriate content is available based on the requesting Agent.
|
89
|
+
And that some content is not available.
|
90
|
+
So that I am upholding any institutional policies and protocols regarding content.
|
91
|
+
|
92
|
+
Scenario Outline:
|
93
|
+
|
94
|
+
Given an Agent with role <role>
|
95
|
+
And a Work of work type <work_type>
|
96
|
+
When the Agent requests the Work
|
97
|
+
Then the Permissions subsystem asserts that the Agent is <access_state> access to the Work.
|
98
|
+
|
99
|
+
Examples:
|
100
|
+
| role | work_type | access_state |
|
101
|
+
| Anonymous | Article | not allowed |
|
102
|
+
| Librarian | Article | allowed |
|
103
|
+
|
104
|
+
Scenario:
|
105
|
+
|
106
|
+
Given an Agent with roles:
|
107
|
+
| role |
|
108
|
+
| Professor |
|
109
|
+
| Librarian |
|
110
|
+
And a Work of work type Article
|
111
|
+
And an Article has the following role-based permissions:
|
112
|
+
| role | access_state |
|
113
|
+
| Professor | not allowed |
|
114
|
+
| Librarian | allowed |
|
115
|
+
When the Agent requests the Work
|
116
|
+
Then the Permissions subsystem asserts that the Agent is allowed access to the Work.
|
117
|
+
|
118
|
+
Scenario:
|
119
|
+
|
120
|
+
Given an Agent with roles:
|
121
|
+
| role |
|
122
|
+
| Professor |
|
123
|
+
| Librarian |
|
124
|
+
And a Work of work type Article
|
125
|
+
And an Article has the following role-based permissions:
|
126
|
+
| role | access_state |
|
127
|
+
| Professor | not allowed |
|
128
|
+
| Librarian | allowed |
|
129
|
+
When the Agent requests the Work
|
130
|
+
Then the Permissions subsystem asserts that the Agent is allowed access to the Work.
|
131
|
+
```
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Proposed Hydramata Timeline
|
2
|
+
|
3
|
+
## Work
|
4
|
+
|
5
|
+
### Where does this exist in Curate?
|
6
|
+
|
7
|
+
Presently the definition of a Work is spread across six major concerns:
|
8
|
+
|
9
|
+
* Model - exposes attributes, validations, defines model level indexing strategy
|
10
|
+
* Datastream - exposes attributes and indexing strategy
|
11
|
+
* Actor - handles input interactions, DOI minting, file uploading
|
12
|
+
* Show page - renders attributes
|
13
|
+
* Edit page - renders attributes (and values)
|
14
|
+
* Index/search result - renders attributes and values
|
15
|
+
|
16
|
+
The sequence of rendered attributes is not kept in sync between the different view contexts.
|
17
|
+
|
18
|
+
### Replacement Strategy
|
19
|
+
|
20
|
+
|
21
|
+
1. Define the narrow public interface for a Work's expected methods and their behavior.
|
22
|
+
This involves providing object linters to verify the API.
|
23
|
+
1. Establish application plugin structure.
|
24
|
+
1. Data-driven presentation structure for Work Types
|
25
|
+
This addresses the rendering aspect of the Show/New/Edit page.
|
26
|
+
1. Splice in a shim for rendering existing Curate work types via data-driven methods
|
27
|
+
1. Data-driven predicate definition for Work Types
|
28
|
+
This addresses indexing strategy, validation, and configurablity of work types.
|
29
|
+
1. Splice in the Work Wrangler to reify Fedora objects
|
30
|
+
1. Splice in WorkActorShim to preserve existing Curate Actor behaviors
|
31
|
+
|
32
|
+
## Workflow
|
33
|
+
|
34
|
+
### Where does this exist in Curate?
|
35
|
+
|
36
|
+
Presently this exists in the Actor and spread across numerous callbacks for Hydra components
|
37
|
+
|
38
|
+
* Creating child GenericFiles under a Work
|
39
|
+
* Derivatives
|
40
|
+
* Remote Identifiers (DOIs)
|
41
|
+
* Generate checksums
|
42
|
+
* Characterization
|
43
|
+
* Assigning a representative image
|
44
|
+
* Running anti-virus
|
45
|
+
* Establish provenance of attachments
|
46
|
+
|
47
|
+
### Replacement Strategy
|
48
|
+
|
49
|
+
1. Create or leverage existing Workflow project (i.e. push Heracles over the hump) to implement an asynchronous messaging system.
|
50
|
+
1. Create single-focus tasks (i.e. hydramata/works/tasks/generate_derivatives) that behave well within the Workflow subsystems
|
51
|
+
1. Replace existing Curate actors with data-driven Workflows.
|
52
|
+
This will obviate the need for the WorkActorShim as the Workflows expect to interact with objects that implement the Work interface.
|
53
|
+
|
54
|
+
## Permissions
|
55
|
+
|
56
|
+
### Where does this exist in Curate?
|
57
|
+
|
58
|
+
This information is spread across:
|
59
|
+
|
60
|
+
* Hydra::AccessControls
|
61
|
+
* The repository manager YML file
|
62
|
+
* The application manager YML file
|
63
|
+
|
64
|
+
The concerns are partially merged into CanCan's expected [Ability class](https://github.com/projecthydra-labs/curate/blob/master/app/models/concerns/curate/ability.rb)
|
65
|
+
|
66
|
+
The enforcement is spread across controllers and views, leveraging both CanCan queries (i.e. `can?(:edit, @work)`)
|
67
|
+
and inline `if current_user.repository_manager?`.
|
68
|
+
|
69
|
+
### How to replace these interactions
|
70
|
+
|
71
|
+
## Administrative Context
|
72
|
+
|
73
|
+
### Where does this exist in Curate?
|
74
|
+
|
75
|
+
No where. This is a yet to be defined concept.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
file = File.expand_path("../../Gemfile", __FILE__)
|
4
|
+
|
5
|
+
if File.exists?(file)
|
6
|
+
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
|
7
|
+
instance_eval File.read(file)
|
8
|
+
end
|
9
|
+
gem 'sass', '~> 3.2.15'
|
10
|
+
gem 'sprockets', '~> 2.11.0'
|
11
|
+
|
12
|
+
gem 'rails', '4.1.0'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
file = File.expand_path("../../Gemfile", __FILE__)
|
4
|
+
|
5
|
+
if File.exists?(file)
|
6
|
+
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
|
7
|
+
instance_eval File.read(file)
|
8
|
+
end
|
9
|
+
|
10
|
+
gem 'sass', '~> 3.2.15'
|
11
|
+
gem 'sprockets', '~> 2.11.0'
|
12
|
+
|
13
|
+
gem 'rails', '4.0.3'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
# Maintain your gem's version:
|
4
|
+
require 'hydramata/works/version'
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'hydramata-works'
|
9
|
+
s.version = Hydramata::Works::VERSION
|
10
|
+
s.authors = [
|
11
|
+
'Jeremy Friesen'
|
12
|
+
]
|
13
|
+
s.email = [
|
14
|
+
'jeremy.n.friesen@gmail.com'
|
15
|
+
]
|
16
|
+
s.homepage = 'https://github.com/jeremyf/hydramata-work'
|
17
|
+
s.summary = 'Provide a well defined data-structure to ease the interaction between differing layers of a Hydra application.'
|
18
|
+
s.description = 'Provide a well defined data-structure to ease the interaction between differing layers of a Hydra application.'
|
19
|
+
s.required_ruby_version = '~> 2.0'
|
20
|
+
|
21
|
+
s.license = 'APACHE2'
|
22
|
+
|
23
|
+
s.files = `git ls-files -z`.split("\x0")
|
24
|
+
s.executables = s.files.grep(%r{^bin/}) do |f|
|
25
|
+
f == 'bin/rails' ? nil : File.basename(f)
|
26
|
+
end.compact
|
27
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
28
|
+
s.require_paths = ['lib']
|
29
|
+
|
30
|
+
s.add_dependency "rails", "~> 4.0"
|
31
|
+
s.add_dependency 'rdf', '~> 1.1'
|
32
|
+
s.add_dependency 'psych', '~> 2.0.5'
|
33
|
+
|
34
|
+
s.add_development_dependency 'engine_cart', '~> 0.3'
|
35
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
36
|
+
s.add_development_dependency 'rspec-rails', '~> 3.0'
|
37
|
+
s.add_development_dependency 'rspec-html-matchers', '~>0.6'
|
38
|
+
s.add_development_dependency 'sqlite3', '~> 1.3'
|
39
|
+
s.add_development_dependency 'rubydora', '~> 1.7'
|
40
|
+
s.add_development_dependency 'vcr', '~> 2.9'
|
41
|
+
s.add_development_dependency 'webmock', '~> 1.18'
|
42
|
+
s.add_development_dependency 'database_cleaner', '~> 1.3'
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'hydramata/works/engine' if defined?(Rails)
|
2
|
+
module Hydramata
|
3
|
+
# Responsible for providing a well defined data-structure to ease the
|
4
|
+
# interaction between differing layers of an application.
|
5
|
+
#
|
6
|
+
# * Persistence Layer
|
7
|
+
# * In Memory
|
8
|
+
# * Rendering/Output Buffer
|
9
|
+
module Works
|
10
|
+
module_function
|
11
|
+
def table_name_prefix
|
12
|
+
'hydramata_works_'
|
13
|
+
end
|
14
|
+
|
15
|
+
# Because I am not using isolate_namespace for Hydramata::Works::Engine
|
16
|
+
# I need this for the application router to find the appropriate routes.
|
17
|
+
# @api private
|
18
|
+
def use_relative_model_naming?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'hydramata/works/conversions/predicate'
|
2
|
+
require 'hydramata/works/conversions/predicate_set'
|
3
|
+
require 'hydramata/works/conversions/presented_fieldsets'
|
4
|
+
require 'hydramata/works/conversions/presenter'
|
5
|
+
require 'hydramata/works/conversions/property'
|
6
|
+
require 'hydramata/works/conversions/property_set'
|
7
|
+
require 'hydramata/works/conversions/translation_key_fragment'
|
8
|
+
require 'hydramata/works/conversions/value'
|
9
|
+
require 'hydramata/works/conversions/work_type'
|
10
|
+
|
11
|
+
module Hydramata
|
12
|
+
module Works
|
13
|
+
# Taking a que from Avdi Grimm's "Confident Ruby", the Conversion module
|
14
|
+
# is responsible for coercing the inputs to another format.
|
15
|
+
#
|
16
|
+
# This is somewhat experimental, though analogous to the Array() method in
|
17
|
+
# base ruby.
|
18
|
+
module Conversions
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'hydramata/works/conversions/exceptions'
|
2
|
+
|
3
|
+
module Hydramata
|
4
|
+
module Works
|
5
|
+
# Taking a que from Avdi Grimm's "Confident Ruby", the Conversion module
|
6
|
+
# is responsible for coercing the inputs to another format.
|
7
|
+
#
|
8
|
+
# This is somewhat experimental, though analogous to the Array() method in
|
9
|
+
# base ruby.
|
10
|
+
module Conversions
|
11
|
+
class ConversionError < RuntimeError
|
12
|
+
def initialize(class_name, input)
|
13
|
+
super("Could not convert #{input.inspect} to #{class_name}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'hydramata/works/conversions/exceptions'
|
2
|
+
require 'hydramata/works/predicate'
|
3
|
+
require 'hydramata/works/predicates'
|
4
|
+
|
5
|
+
module Hydramata
|
6
|
+
module Works
|
7
|
+
module Conversions
|
8
|
+
private
|
9
|
+
def Predicate(input)
|
10
|
+
return input.to_predicate if input.respond_to?(:to_predicate)
|
11
|
+
|
12
|
+
case input
|
13
|
+
when Predicate then input
|
14
|
+
when String, Symbol then Predicates.find(input)
|
15
|
+
when Hash then Predicates.find(input.fetch(:identity), input)
|
16
|
+
else
|
17
|
+
raise ConversionError.new(:Predicate, input)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|