hydramata-works 0.0.1.prerelease
Sign up to get free protection for your applications and to get access to all the features.
- 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
|