OOP Design: Where should reusable validation be? - oop

I've got a wizard which needs to validate if a user is logged in and then at the end validate that all the details they have entered are correct.
The issue is I'm not sure where to put the validation logic.
At the moment I have a BuyMembership class which has validation on the Buy() method.
However this won't be called at the beginning of the wizard where I need to validate whether the user is unique and is eligible for buying a membership.
For this validation I've created a BuyMembershipValidation class which validates if the user is eligible.
The issue now is that I have to pass a different parameter object to the BuyMembershipValidation and the BuyMembership classes. This means the data is split.
Is there a better way of doing it. Should I only load part of the information into the BuyMembership class for the initial validation and then load the rest after?
Update:
I need to validate when they enter the wizard (check if they are logged in already) and if they aren't then they will register as a new user otherwise I have to check if they have the right settings to buy membership as all users can't buy a membership. That's why I need two sets of validation. One for whether they're eligible and another for the actual data they enter to register. However I would like to recheck that they are eligible when they make the final transaction just in case they somehow made it past the first wizard step or if the web service (where I'm doing the logic) is called from somewhere else at a later point.
Another Update:
I've added an answer with my decision.
TIA,
Jonathan.

You're actually talking about three very different things here, and like Allain said, you need to think along the lines of single-responsibility to do this right, OOP-like.
Authentication: making sure a user is known
Authorization: making sure a user can access certain logic in your application
Validation: making sure the data a user inputs is valid/safe/what's expected or needed

A validator is typically tasked with validating user supplied information, not authorization. The single responsibility principle dictates that in your case they should definitely be handed by two objects.
Passing different parameter objects is fine, but but I think the authorization one shouldn't really be passed in to the BuyMembership object, it sounds like something that should be handled externally to it.
My 2 cents.

User authentication is a broad topic. It really depends on what type of application you are building. If it is a web application, I would recommend using one of the standard methods for authentication: NTLM / kerberos
As to when to validate, I don't see any problem with holding off on the validation until the actual Buy method is called. As long as during the steps in the wizard, you are not releasing any information to them and are only collecting data from a form. The main time when you need to be concerned about authentication is when you are actually placing an order or releasing information to the user that should be locked away in a database somewhere.
If you provide more details to what you are trying to do, I will refine my answer to help you a bit more. It's a rather broad question though, so this is the best I can come up with for now.

I've decided to go with just the one class. The reason is that there is common logic / behaviour in the IsEligible and Buy methods. One determines if the inputs meet the eligibility requirements and the other validates that all the details needed to buy the membership are valid. I don't really see this as authentication related. The authentication is done in a separate web control and I just check the Identity.IsAuthenticated and Username to see if they are logged in. I then check their username and if they are eligible to buy then I let them continue, otherwise show an error message. In terms of input validation I already have validation controls on my webpage but the validation I'm concerned with here is server side business logic validation. For that reason I think it should be in the business logic class. Not some validation class separate from the logic that performs the payment. This may just be my way of looking at it but I think this fits well with the BDD ideas of keeping validation inside the entity that holds the data.

Related

How to use AuthenticationSchemeOptions.Events or AuthenticationSchemeOptionsEventsType?

Ok, so as per usual, MSDN is now an automatically generated blob of useless documents, so maybe the developers lurk around here and can explain this to me.
I created a custom Authentication scheme based off of the AuthenticationHandler<TOptions> base class. I have two questions regarding this:
How do I define the type to use in AuthenticationSchemeOptions.EventsType in order to consume authentication-related events?
If the loggerFactory object a required object? Can't I just pass null to it? I want to control my output. I guess I could test this one myself. If you want to answer, go ahead, otherwise I'll test it at some point.
But what I have no clue whatsoever is for question 1. I see the class JwtBearerEvents as a sample, but I have no idea if I should be creating one exactly like that, or in general, how does this event system works at all???? I am utterly confused.
Thank you.
P. S.: I don't think it is important, but just so you know, the custom authentication handler basically validates a JWT created by a federated API server whose signing keys can be queried to verify signature. So basically it is a handler that makes a web request (then caches the keys) and uses those keys to validate the token and extract the claim data of interest, finally creating a ClaimsPrincipal user out of said claims.

Testing Best Practices possibly with regard to Gherkin but probably not

A coworker and I are having an argument about the proper way to test. I'll lay them out as neutrally as I can, and won't give my opinion in this post.
This is written in gherkin. Substitute whatever pseudocode you want to.
Given I am a registered user
When I submit my credentials
Then I can login
Case one:
Given I am a registered user
(instantiates the user,
stores the user to scenario-global memory,
adds the user to the db with an API endpoint
stores the API endpoint result to scenario-global memory [200, "Success message"])
When I submit my credentials
(test the result of the previous step [200],
fills the credential field(s),
clicks submit, stores the result to scenario-global memory [200, "Success message"])
Then I can login
(tests the results of the previous step)
Case two:
Given I am a registered user
(instantiates the user,
stores the user in scenario-global memory,
adds the user to the db, tests the result of the db command)
When I submit my credentials
(fills the UI credential field(s),
clicks submit)
Then I can login
(perform some operation that only a logged-in user could do [see the my profile button/call some api endpoint])
​
The contention is whether or not the Then step can rely on the result from a previous operation.
It depends. First of all, as a tester, i would never directly write something to DB, instead i register the user in UI for UI testing or call endpoints to cover API testing scenarios.
Also, IMO, not every step is responsible for testing its own step, otherwise there is no need for 'Then' Gherkin syntax. This way of writing user stories makes it more understandable to non-technical but business people very clearly about the scenario under test.
For both cases above, i vote for case one and your co-worker's suggestion.
Overall, one should aim for declarative BDD scenarios, when trying to cover the features from end-user perspective. Pushing your how down is vital part of it. Employing Back door manipulation is great, but ask youself this - does your end user (or stakeholder) really care about technicalities?
adds the user to the db with an API endpoint
is something that is best used, when the register user flow is covered at least once through the UI. Mixing APIs and UI in the scenarios, can lead to a mess and maintenance issues. A proper DSL should handle that for you.
As to
each step is responsible for testing its own results. It is not responsible for what happened in the past or what is about to happen in the future
Cucumber-ish frameworks do use DI of context/state, exactly for this - share steps execution run in the current World instance.

Ignore or not API endpoint parameters based on access level

I am working on an API endpoint that returns a list of products:
"api/products"
The endpoint accepts the following parameters:
page_size
page_number
Each product has a boolean property named IsApproved.
In the web application used by common users I always want to return only the Approved products ... On the web ADMIN application used by administrators I want to return all products, Approved or Not ...
My idea would be to add a new parameter (enumeration) named:
ApprovedStatus
And the values would be Approved, NotApproved and All.
On each API call I would check the user permissions ... If is admin I will consider the value on this parameter. If not then I will always return only approved products.
Another solution would be to have different endpoints ...
Any advice on which approach to take or is there other options?
The approval status is part of the product, therefore, in a perfect REST world, you don't want a different endpoint at all since you're accessing the same resource.
Then, for filtering a resource based on a property value, I think the convention is that if you specify that property as a query parameter it will only return those matching the value, and if not, it will return all of them, so I don't see the need to define a special ApprovedStatus parameter with some special values. Just query by isApproved!
Finally, about how to handle authorization. This, I think, should be handled at a completely separate layer**. If authorization is involved, you should have an explicit authorization layer that decides, for a specific resource and user, wether access is granted or not. This means the query would be triggered and if one of the resources generated by the query fails to be authorized for the user that triggered the query, it's taken out of the results. This accomplishes the behaviour you want without having any code that is checking specific users against specific query parameters, which is good because if tomorrow you have another endpoint that exposes this objects you won't have to implement the same authorization policy twice. Pundit is a perfect example on how to do this with Ruby elegantly.
**Of course, this approach retrieves data from the database unnecessarily which could matter to you, and also opens your endpoint up to timing attacks. Even then, I would consider tackling these problems premature optimizations and should be ignored unless you have a very good reason.
You're right about your ideas:
You can create a new endpoint just for admins, that will return all products
You can use a kind of authorization (e.g. Authorization Header) in order to check if the API is being called through admin or normal user. Then you can route internally to get all products or just IsApproved products.
You can add a proxy in front of your API to route to the right action, but it can also be achieved directly in the API but I think the second solution is easier.
Adding one more property is a bad idea.
In my opinion, adding another end point is very good. Because it will increase the protection in the admin end point.
Otherwise, since it is a web application, Simply set a cookie and a session to identify and separate the admin and user.
Going with the principle of least astonishment, I'd be in favour of adding a second endpoint for admin users. Such that you'll have:
GET /api/products (for regular users)
GET /api/admin/products (for admins)
This allows your code and API documentation to be nicely separated, and all of the admin-specific authentication details can live under the "admin" namespace.
The intention behind each API call is also clearer this way, which helps developers; and means that you can differentiate between admin vs regular usage in any usage stats that you track.
With ApprovedStatus, I think the specifics here don't matter much, but - considering what a developer using the API might reasonably expect / assume - it would be good to:
Ensure the ApprovalStatus parameter name matches the property name for "approval" that you return with each product object
Defaults to "approved" if it is not specified
Alert the user when an invalid value is specified, or one that they don't have access to
Bottom line: to answer your headline question - I think it's bad practice to ignore user input... sometimes. Design your API such that distinctions around when input can be passed in is very clear; and always alert the user if you receive input values that are technically acceptable, but not in the way that the user has requested, or for their access level. Ignoring values that are plain wrong (e.g. an argument that doesn't exist) is another story, and can be useful for future proofing or backwards compatibility.

How to handle yodlee MFA?

There's almost no documentation on anything in yodlee. I have managed to correctly handle getLoginForm by just inspecting the JSON objects returned by different sites until I was able to handle all such forms.
What I don't understand is how to get the MFA fields, what makes them different, and how I submit them differently from the regular login form fields.
I'm new to the system, can anyone with some experience explain this to me?
MFA fields are security questions/tokens/images asked as a follow up from the typical login/password (although you'll soon learn there is nothing typical in the obscure world of bank authentication).
You get the MFA fields by calling getMFAResponse (once you've gotten an ItemID from your addItemForContentService1 call) - http://developer.yodlee.com/Indy_FinApp/Aggregation_Services_Guide/REST_API_Reference/getMFAResponse
Which you then use to build another form, and take that input and submit it with putMFARequest - http://developer.yodlee.com/Indy_FinApp/Aggregation_Services_Guide/REST_API_Reference/putMFARequest

Appropriate way for business logic layer to deal with its neighbors?

Good morning, i have a use-case in my project that says that If the user isn't logged in to the application display a warning message to him and what determines if the user is logged in or not is a managed bean called loginPageCode, a class in the business logic layer will be responsible to determine if the user is logged in or not in order to take a decision for displaying a message(that action will be taken when a specific action occurs in a JSF page called home.jsf), i thought of 2 approaches to do that as follows:
Make the home page determine if the user is logged in or not and pass the final decision to the business logic class
Make the business logic class be responsible for determining if the user is logged in or not and that will require it to deal directly with loginPageCode
i want to know the suitable way of doing that from the point of design.
If the business logic layer needs to know if the user is logged in, you should just pass along that information as an argument.
The business layer should not need to know HOW the user is authenticated, if it needs to know if the user is logged in it should be given that information -- that's separation of concerns for you! :)
The main idea is that you can always reuse the same business rules even in an entirely different environment, e.g, using a different authentication mechanism.