Filters messages to those matching the requesting user's groups.
Problem with this solution:
This changeset implements group filtering based on isMemberOf header. This will work great for groups available from UW-Madison's IdP, that is, "Manifest" groups. This won't work at all for other groups (e.g. uPortal PaGS groups) and other IdPs (hi, UW-System!) that don't set this header. We'll need to either rationalize how we present groups to microservices (get other campuses to set isMemberOf, virtually set that from other sources, something?) or implement another way of getting groups (uPortal groups API? How?)
Changes:
/messages is now the filtered-to-user path (had been /currentMessages, which is no more).
/allMessages is now the all-the-messages path (had been /messages).
Features:
filters messages so they are only seen by users who are members of at least one group in the message's audience, in cases where messages have an audience filter specifying groups.
Adds rudimentary User model, parsing user groups from isMemberOf header.
AudienceFilters are now able to apply themselves to Users to answer whether they "match" that user (whether the user is in the audience), as Predicate<User no less.
Refactors:
Introduces Repository layer to architecture, moving text file reading and parsing out of the Service and into this new Repository layer.
Tradeoffs navigated:
Identity and authorization needed is currently very simple, such that arguably it's okay to introduce an ad-hoc User to the model, determined from the Request in the Controller layer, passed on to the Service layer, etc. Alternatively could be using something more elegant, e.g. Spring Security or Shiro.
I didn't understand the existing MessagesControllerTest or how to add to it the kind of Mockito mocked unit tests I know how to write generally for Java regardless of all this Spring stuff. So I introduced a MessagesControllerUnitTest to house no-magic-MVC-context vanilla JUnit/Mockito tests for that controller. Upshot is reasonable confidence this changeset doesn't break things (through test scaffolding) but not rationalizing how unit tests are implemented for this controller.
Refactoring to make the service layer speak domain objects rather than JSON is probably a good idea, but this changeset doesn't do it.
security: NOT implementing access control, punting that to container layer.
configurability: NOT making microservice configurable as to what filtering it's doing. It's configurable within the domain model in that AudienceFilters are optional for messages: no filter, no filtering by group.
configurability: NOT making name and nature of header specifying group memberships configurable, since arguably we only need isMemberOf.
security and validation: NOT implementing extra validation/sanitization on isMemberOf header. Hypothetically a do-badder could implement a DoS attack by feeding the microservice an arbitrarily huge isMemberOf header value which would be expensive to parse. To the extent that isMemberOf header size should be limited, that limiting should happen at container/httpd layer and doesn't need to be here.
[x] Documented (README updated, JavaDoc added).
[x] Fails gracefully (handles missing isMemberOf, handles no AudienceFilter).
[x] Tested (Covered by unit tests, manually tested as running Boot service).
[x] Secure (Exception).
[x] Adds no defects (At least none that the automated tests detect.)
[x] Shippable. Path is clear to promote to production. (We're in 0.1.0 status. This changeset makes the product no less releasable.)
[x] Maintainable
[x] Configurable (Exception.)
[x] Readable
[x] Validates and sanitizes user input (Exception.)
Filters messages to those matching the requesting user's groups.
Problem with this solution:
isMemberOf
header. This will work great for groups available from UW-Madison's IdP, that is, "Manifest" groups. This won't work at all for other groups (e.g. uPortal PaGS groups) and other IdPs (hi, UW-System!) that don't set this header. We'll need to either rationalize how we present groups to microservices (get other campuses to set isMemberOf, virtually set that from other sources, something?) or implement another way of getting groups (uPortal groups API? How?)Changes:
/messages
is now the filtered-to-user path (had been/currentMessages
, which is no more)./allMessages
is now the all-the-messages path (had been/messages
).Features:
isMemberOf
header.AudienceFilter
s are now able to apply themselves toUser
s to answer whether they "match" that user (whether the user is in the audience), asPredicate<User
no less.Refactors:
Tradeoffs navigated:
User
to the model, determined from the Request in the Controller layer, passed on to the Service layer, etc. Alternatively could be using something more elegant, e.g. Spring Security or Shiro.MessagesControllerTest
or how to add to it the kind of Mockito mocked unit tests I know how to write generally for Java regardless of all this Spring stuff. So I introduced aMessagesControllerUnitTest
to house no-magic-MVC-context vanillaJUnit
/Mockito
tests for that controller. Upshot is reasonable confidence this changeset doesn't break things (through test scaffolding) but not rationalizing how unit tests are implemented for this controller.Definition of Done
Exceptions to Definition of Done:
security: NOT implementing access control, punting that to container layer.
configurability: NOT making microservice configurable as to what filtering it's doing. It's configurable within the domain model in that
AudienceFilter
s are optional for messages: no filter, no filtering by group.configurability: NOT making name and nature of header specifying group memberships configurable, since arguably we only need
isMemberOf
.security and validation: NOT implementing extra validation/sanitization on
isMemberOf
header. Hypothetically a do-badder could implement a DoS attack by feeding the microservice an arbitrarily hugeisMemberOf
header value which would be expensive to parse. To the extent thatisMemberOf
header size should be limited, that limiting should happen at container/httpd
layer and doesn't need to be here.[x] Documented (README updated, JavaDoc added).
[x] Fails gracefully (handles missing
isMemberOf
, handles noAudienceFilter
).[x] Tested (Covered by unit tests, manually tested as running Boot service).
[x] Secure (Exception).
[x] Adds no defects (At least none that the automated tests detect.)
[x] Shippable. Path is clear to promote to production. (We're in
0.1.0
status. This changeset makes the product no less releasable.)[x] Maintainable
[x] Configurable (Exception.)
[x] Readable
[x] Validates and sanitizes user input (Exception.)
[x] Styled (No style is defined for this repo.)