I'm using ActiveRecord to maintain information about users. The User class has the expected load(), insert(), update(), and delete() methods, setters, getters, and a few others. But I am having trouble deciding whether or not certain other methods should be included in the User class, or handled by collaborators.
Here's an example:
There are several transactions that a user might request that require confirmation. This is handled in a conventional way -- sending an email to the user with a link; clicking the link confirms that the user does indeed want the transaction to proceed. A hash of the verification key and it's expiration date/time persist as part of the user record.
Where should I draw the line in this process? Should there be a collaborator that handles verification (for example by taking the plain-text verification key from the query string and accepting a User object as a param)? Or should this be handled internally by the User class (passing the plain-text verification key in a method call)?
The very next thing that would happen upon verification, of course, is that the transaction would proceed requiring an update to the active record -- and there, it seems to me, the User class must have responsibility.
Any suggestions?
You should delegate this task to a collaborator, which manages a confirmations table.
You would use the Confirmation model to track all confirmation requirements. The model will belong to User, as well as manage the confirmation hash and the action-to-be-confirmed (e.g. activate_account, change_password or change_email etc.).
The Confirmation controller would be responsible for validating the confirmation hash and chaining the appropriate action on the appropriate model (e.g. activate_account -> user.activate(), change_password -> user.setPassword() etc.) and remove the Confirmation from the confirmations table upon successful completion.
This will allow for better separation of logic, as well as allow you to scale better, e.g. to entertain more than one pending confirmation for a given user (say confirmation to change password and confirmation to change something else.)
Related
I want to make a service that allows to bind private user's channels to a user's account.
The user opens a private channel with my node. But I don't know which user exactly.
To identify the channel, I plan to ask the BOLT11 request from user, with a unique identifier in the description, like an SMS code.
BOLT11 specifies the target address of the payment. I will find a route for this request and thus determine the user's channel.
Is such a scheme safe? Can a fraudster create a BOLT11 request for a channel that does not belong to him? Сan you suggest a better identification scheme?
Can a fraudster create a BOLT11 request for a channel that does not belong to him?
Bolt 11 states:
The recovery ID allows public-key recovery, so the identity of the payee node can be implied
I'm not sure how every implementation matches the specification here. I would assume that all of them perform signature verification, but they might not expose public-key recovery functionality. Your idea of finding a path without actually paying the invoice might work.
However it seems that what you need is actually to identify an existing private channel between your node and the user's. Private channels should be included as routing hints in the invoice, so it might even be easier to get it from there by just decoding the invoice.
An alternative option would be to ask the user to pay an invoice generated by your node, a msat would be enough. For sure she won't be able to craft a payment with a node she doesn't control.
The safest way would be if the user signes a message with one of the keys that he uses to sign commitment transactions. This would certainly bind his identity to the channel. However current implementations don't offer that api. But that does not mean that this would not be possible
Based on the information given at https://fusionauth.io/docs/v1/tech/apis/users#update-a-user it seems that any API key that allows access to this endpoint can update any user record.
I am missing a method of authorization based on a JWT for this endpoint so that any user can update his/her user record.
What is the recommended practice to handle this?
FusionAuth does not currently allow you to call the Update User API with a JWT issued to the user you're trying to update.
There are a couple of reasons for this. the first is that not all implementations would agree this is a safe operation for an end user to perform. The second is that because the custom data on the user and registration objects will be indexed by Elasticsearch. Elasticsearch creates a dynamic schema based upon these values which means it will expect the schema not to change.
For these reasons, and perhaps others, it is much safer to allow an API written by the FusionAuth implementor to handle this process.
That is all to say, you will want to call the Update User API on your end so you can control what is updated and perform any necessary validation on custom data.
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.
The application is written in Ruby on Rails but the problem I am facing is more a design matter than language related.
the system provides service to a number of users to maintain a registry. So it relates persons to things. As such it has a model called Person representing owners and it has a model called User representing those who manage the registry.
Now a new requirement has arisen to allow People to log in and be able to change personal details which it was not required for the original design.
The question is how to refactor the application to allow this new requirement in?
One easy solution is to create Users for each person who request login credentials and link user to person entity but that is not very DRY as some fields such as firstname, surname etc. are in both classes and in particular, that is precisely the data people will be able to change. Besides User and Person are stored in separate tables.
The other possibility I was considering is to make one to extend the other but having data in separated tables it makes it a bit messy. Additionally the logical extension would be User <- Person as an user is (generally) a person but thinking on the implementation Person <- User is quite a lot easier.
One last option could be to scrap User and move login credentials into Person leaving logon fields empty for those who won't log in and half of the fields empty for those just login in.
Can you think of a better solution?
You could think about how this should ideally work if you were to write the application bottom-up, and then figure out how to make a reasonable compromise between that and your current setup. Here are some generic inputs.
As authentication is involved, you need an "Identity" that can be authenticated. This can be e.g. an email address and an associated password, with email verification.
An Identity can potentially be associated to multiple "Roles" and someone authenticated with the identity can choose which role to perform, e.g. "I am now an administrator" vs. "I am now a regular site user", and the role defines the user's current rights for the logged in identity. Or if you don't need that level of complexity, you can say that an Identity is a (single) Role.
You need some tracking between possible "Rights" and the Role the user is performing. E.g. the simplest setup could be the Identity or Role has some boolean can_edit_profile or can_modify_registry properties.
Whenever a user attempts to perform an action which requires certain Rights, it is simply a matter of looking up the corresponding rights set for the Role being performed by the user, to check whether the user is allowed to proceed.
For your application this may just involve adding a 'can_change_registry' property for your user objects, and check whether that property is True for any code accessing that part of the site.
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.