I have two questions related to Udi Dahan's article : Don’t Delete – Just Don’t
Sometimes we do need delete, the user (domain expert) request the delete functionality(the real meaning) for wrong data, Say the HR user has a form to add employees and he inserted wrong employee data, He wants to delete this data, It's not used in business yet and it's totally different from Retire or Fire an employee. How to handle the two cases in implementation?
How to make the UI more representative for this case ? using two buttons One shown only if we can DELETE employee and the other if we want to RETIRE employee ?
If the business wants this functionality and if they speak this words then it means they are part of the Ubiquitous language. In this case you may add the delete command. It is however recommended to make the intention clearer; you can name the command as deleteUserBecauseOfInvalidRegistration or so. In this case the delete command is part of the domain model; this means that you can easily restrict the deletion of the user depending on the other properties; for example, a user cannot be deleted anymore if it has approved by the HR manager or so. Then the UI can easily reflect this behavior by hiding the delete button if the operation is not permitted.
An alternative, when the business specialists have heard the word "delete" used by the IT guys so its not from the real domain, you may expose this functionality only in the Admin UI, as a low level command that deletes the rows from the database. The Admin UI could then be accessed only by some higher level persons, like the HR manager.
Related
In Lotus Notes/Domino, we have the functionality of Readers fields, which I know all about. These say who CAN see a document. I would like to know if there is some way (may be undocumented) where you can have that type of thing that says specifically who CANNOT see a certain document.
We have an application for HR, and some of the documents in there reflect negatively about certain people (complaints, for example) and everyone who has access to the database currently can see every document. I would like to hide this type of document from that specific person. I have not enacted any Readers fields on any documents in question.
It would be really nice to have a way to keep that current setup, but insert a factor of who to HIDE the document from like Readers fields do.
I know there are undocumented features people have learned about over the years, and wondered if anyone knows of such a thing that I can use.
Create a role called [ReadAll].
Create a Group called HR Readers and one called HR Restricted.
Add the people who can't read documents to the HR Restricted group. Add all others to HR Readers.
Add these two groups to the ACL and give the HR Readers group the [ReadAll] role.
Add a readers field that is computed to "[ReadAll]" on the documents you want to prevent the people in the "HR Restricted" group to not see.
No, there is no feature that does what you want. Not on a user-by-user basis. You can play with groups and roles, as suggested by Rob Mason, but those groups and roles have to be pre-determined. We asked for Non-Readers fields (at least) 20 years ago so that we could do what you want, but Iris, Lotus, IBM, and HCL never did it. I presume that either (a) it's hard, or (b) there isn't enough demand. Or both.
To hide content from specific people, you can use hide-when formulas within a form. I.e., the hide-when formula on one or more sensitive fields would be set to
#isMember(#UserName; RestrictedUsers)
where RestrictedUsers is a field that contains the list of people who cannot see the data in the fields.
But this is not real security. A user can see the document in views, and can see the hidden fields by bringing up the document properties dialog, or with a tool like NotesPeek. If you're talking about a Domino web app, and users don't have Notes clients and you have strictly-managed desktops so you are sure that is the case+, then it kind of sort of works. Admins and developers, though, would probably have the clients and would be able to see fields in documents that they're not supposed to.
I believe if I simply compute a Readers field to say something like:
whoToHideFrom:="John Smith/org";
#Name([ABBREVIATE];#Username) != whoToHideFrom
I will try this and mark this as successful or not successful after I test it
Should database be verifying if user is authorized to perform certain action?
Two examples:
1)User is enrolled in 30 teams max and it can see scoresheet of these teams only. I'm passing in userid and teamid to the stored procedure and fetching the scoresheet only if user is authorized to view the scoresheet. Is it more appropriate to only pass in only teamid and check beforehand what all teams user is enrolled in? Should I do both?
2)Currently I'm passing in userid of the poster and the commentid of the comment to be deleted and I'm deleting comment only if both criteria is met - userid matches to the poster id and commentid matches to the commentid - just to make sure user is deleting his own comment and not somebody else's. Is it an overkill?
Multiple layers of validation is best practice and it doesn't seem like your methods would cause additional overhead. Just make sure to limit connecting to the database once, I've found that the most costly part of running database queries is the connection and cursors.
http://msdn.microsoft.com/en-us/library/aa174437%28v=sql.80%29.aspx
Security experts will tell you that No amount of security is enough! But at the same time you have to find a balance b/w security and unnecessary layers of protection that are bound to affect your application's performance.
Answering your 2nd question first: It is a good idea to pass both userid as well as commentid, and matching both, so that you accidentally don't delete all comments by a particular user.
Coming to your 1st question now: As I understand it, you want users only part of the team to be able to view the team's scoresheet, right? In order to do so passing only the teamid of all the teams the user is a part of will do. I am not sure what you mean by authorization here!
NOTE:
I have answered your question from a theoretical view with no idea about your Table structure or whats written in your Stored Procedures.
Your frontend is a much more friendlier (libraries, frameworks, best practices) environment to implement whatever access restrictions or authorization that you could possibly have in mind. Adding another layer inside the database just adds a lot of complexity and duplicate implementation of your access restrictions.
I would only consider doing it if clients connect and execute commands directly against the database.
So, rely on the ids provided by the application and spend your energy on sanitizing user input and implementing a sane authentication model. You will need it.
Currently I am developing an API and within that API I want the signed in users to be able to like/unlike or favorite/unfavorite two resources.
My "Like" model (it's a Ruby on Rails 3 application) is polymorphic and belongs to two different resources:
/api/v1/resource-a/:id/likes
and
/api/v1/resource-a/:resource_a_id/resource-b/:id/likes
The thing is: I am in doubt what way to choose to make my resources as RESTful as possible. I already tried the next two ways to implement like/unlike structure in my URL's:
Case A: (like/unlike being the member of the "resource")
PUT /api/v1/resource/:id/like maps to Api::V1::ResourceController#like
PUT /api/v1/resource/:id/unlike maps to Api::V1::ResourceController#unlike
and case B: ("likes" is a resource on it's own)
POST /api/v1/resource/:id/likes maps to Api::V1::LikesController#create
DELETE /api/v1/resource/:id/likes maps to Api::V1::LikesController#destroy
In both cases I already have a user session, so I don't have to mention the id of the corresponding "like"-record when deleting/"unliking".
I would like to know how you guys have implemented such cases!
Update April 15th, 2011: With "session" I mean HTTP Basic Authentication header being sent with each request and providing encrypted username:password combination.
I think the fact that you're maintaining application state on the server (user session that contains the user id) is one of the problems here. It's making this a lot more difficult than it needs to be and it's breaking a REST's statelessness constraint.
In Case A, you've given URIs to operations, which again is not RESTful. URIs identify resources and state transitions should be performed using a uniform interface that is common to all resources. I think Case B is a lot better in this respect.
So, with these two things in mind, I'd propose something like:
PUT /api/v1/resource/:id/likes/:userid
DELETE /api/v1/resource/:id/likes/:userid
We also have the added benefit that a user can only register one 'Like' (they can repeat that 'Like' as many times as they like, and since the PUT is idempotent it has the same result no matter how many times it's performed). DELETE is also idempotent, so if an 'Unlike' operation is repeated many times for some reason then the system remains in a consistent state. Of course you can implement POST in this way, but if we use PUT and DELETE we can see that the rules associated with these verbs seem to fit our use-case really well.
I can also imagine another useful request:
GET /api/v1/resource/:id/likes/:userid
That would return details of a 'Like', such as the date it was made or the ordinal (i.e. 'This was the 50th like!').
case B is better, and here have a good sample from GitHub API.
Star a repo
PUT /user/starred/:owner/:repo
Unstar a repo
DELETE /user/starred/:owner/:repo
You are in effect defining a "like" resource, a fact that a user resource likes some other resource in your system. So in REST, you'll need to pick a resource name scheme that uniquely identifies this fact. I'd suggest (using songs as the example):
/like/user/{user-id}/song/{song-id}
Then PUT establishes a liking, and DELETE removes it. GET of course finds out if someone likes a particular song. And you could define GET /like/user/{user-id} to see a list of the songs a particular user likes, and GET /like/song/{song-id} to see a list of the users who like a particular song.
If you assume the user name is established by the existing session, as #joelittlejohn points out, and is not part of the like resource name, then you're violating REST's statelessness constraint and you lose some very important advantages. For instance, a user can only get their own likes, not their friends' likes. Also, it breaks HTTP caching, because one user's likes are indistinguishable from another's.
i am currently having a problem, i guess a lot of people have run into before and i would like to know how you handled it.
So, imagine you have 10.000 Users on your App. ( each one has an own user/pw login to administrate his stuff ).
Imagine further, that you have a growing normalized SQL-tablestructure in the backend, with tables like: Users, Orders, OrderPositions, Invoices, etc.
So, to show/edit/delete stuff of a table which isn't the usertable itself, u'll probably have links like these, to let ypur users interact with the application.
~/Orders/EditOrder?id=12
~/Orders/ShowOrderPosition?orderId=12&posId=443
Ok, and now the problem:
How, do i prevent in a "none-complex"-way, that user A has access ( show/edit/delete ) the data of user B.
Example:
User B calls:
~/Orders/ShowOrderPosition?orderId=12&posId=443
which is an order of user A, so user B should have no access to it.
So, in my code i would need to have a UserIdentity-check before or within every single SQL-statement, like:
select * from OrderPosition op, Order o, User u
where op.Id = :orderId
and op.Fk_OrderId = :orderpositionId
and o.Id = :orderId
and o.Fk_User = :userId
Only this way i can make sure, that the data belongs to the requesting user.
To reach the usertable will of course get far more complex, the deeper the usertable-connection is "buried" in the normalization ( imagine tables like payments or invoices, connected to the order-table... )
Question:
What is your approach to deal with this, concidering: Low complexity, DRY and performance
( Hope u understand what i mean ;) )
This is a bit like a multi-tenant application - I have gone down this route and denormalized an ID onto all those tables that require this kind of check (a tenant ID, in your case, sounds like the user id).
I then created an interface that contains this field only and applied it to all those classes in my model layer that required this access.
In my base data access (repository) class, where all the select/update/delete calls go through, I then check to see if the class if of the type of that interface, and I then check that the current access matches that ID.
Of course, this depends on how your code is structured, and how simple/complex making this global kind of change will be...
Never expose ids.
And if you have to: encrypt them.
Performance
for ultimate performance you will have to denormalize to the point that reading the row and comparing with some application level variable would give you an answer on what kind of rights the user has (this is fairly fast and if your DAO/BAO level is well organized plugging it in will keep it relatively DRY and at relatively low complexity.) NOTE: complexity is also a function of your security model, once you start to implement inheritable, positive and negative, role-based access rules then it can not be really simple.
DRY
another route to take (which is very seldomly taken these days) is to use your database roles to manage security; this might get complicated but will offer unparalleled security (as it will be ensured at the DB level and not application level. Complexity should go down, at the application code level, if you manage to encapsulate all of your access paths into VIEWS, which might require quite a bit of re-tailoring at the database level. However(!), it might be possible to implement security model with very little changes to the application code - by renaming existing tables and replacing them with secured views)
Don't use your internal ID column, encrypted or not, it'll come back to bite you one day.
Create a random, unique, string (GUID, whatever), which contains the link between the user and the data he's requesting. So, instead of having, for user 34567:
Edit order
Create a record {"5dsfwe8frf823jrf",34567,12} in a temporary table and show:
Edit order
When the users clicks the link, fetch 34567,12 from your temporary table.
The string 5dsfwe8frf823jrf is impossible to guess = no security risk.
I'm trying to make the domain model of a management system. I have the following kind of people in this system:
employee
manager
top mananger
I decided to define an User, from where Employee, Manager and Top Manager will specialize from.
Now, I don't know what kind of specialization hierarchy I should choose from.
I can't decide between the following ways:
or
Which might be preferable and why?
As a long time coder, every time I try to do a domain-model, I have to fight against the idea of trying to think in how I'm going to code this. From what I've understood, I should not think about those matters in the domain-model, only in object relationships. I don't have to think of code duplication or any of these kind of details here, so I can't really pick any of the options over the other.
Thanks
EDIT:
I'll be a bit more explicit: This is a program to manage worker's vacations plans. With this program, a employee can choose the set of vacations days for the year. Then the manager might approve or not those days for each one of the employees and at the end of the day the top manager should approve or disapprove the manager's decisions. This is all the users of my program are supposed to be able to do. There are no other tasks.
This mostly comes down to a question of how you define your terms. The basic question is whether a manager can be substituted for an employee under any possible circumstances -- and without knowing the precise rules of the workplace being modeled, it's impossible to say one way or the other about that.
One general notion is that yes, at least up to a certain point, in a pinch a manager should be able to do the job of any of his subordinates (at least one level below, and quite possibly two or three).
On the other hand, in some places with lots of union-driven rules in place, that may not be the case at all. Even if a person is entirely capable of doing a job, rules may prevent him from substituting in that position at all. In some cases this arises from certification requirements and such (e.g., the manager may have one been qualified to do the work, but the required certification has lapsed) or from things like union rules (e.g., a friend of mine who was once reprimanded because he carried a flashlight bulb and battery from the company store back to his lab instead of getting a union materials handler to do that for him).
In real life, Managers are Employees too. So this is surely just a chain of increasing specialisation:
User -> Employee -> Manager -> Top Manager
edit
"This is a program to manage the
vacations plans of workers."
In you company do Managers take planned vacation? Surely they do. And equally surely you are not going to build a separate application to manage that. So what you really need is this:
User -> Requester
-> Approver
Each User will be a Requester in one approval chain. (You may need special arrangements for the CEO). In addition some Users will be Approvers in one or more chains. The final approver will probably vary depending on the grade of the Requester: the CEO won't want to bother themselves with approving the vacation arrangements of the janitorial staff.
You will need some rules to enforce who can be an Approver of any given Requester's holidays. Unless you have an exceedingly flat organisation you will find you have a hierarchy of workers and managers. For instance, a Team Leader or a foreman - individuals who are in other respects "workers" rather than "managers" - may be in the chain. Also you may need to consider other aspects of the organisation. Fr instance, if the employee wishes to carry leave over to the next year that may require approval from the HR dept, somebody who normally has no managerial responsibility for the employee whatsoever.
Edit 2
Okay, so we are modelling an arbitrary set of rules rather than a realistic scenario.
Let's see. Each User fits into a single category, defined by these tasks:
an Employee can Request leave
a Manager can Approval or Reject a Leave Request
a Top Manager can Accept or Overturn an Approval or Rejection
Managers and Top Managers have no behaviours in common. Consequently, the first model is the correct one.
I would model these as actors. They are not the domain of the system, but the users of the system. Would you model a shop's inventory system with 'school-kid who wants sweets', 'school-kid's parent who wants tobacco', 'clerk' etc? Although only a store manager (actor) can give refunds without a receipt, what matters at the system level is that system recognises the store manager's key, and it's that permission token which is in the software rather than role the actor takes.
The domain of the system you describe is vacation requests and the user account, and some of the use cases mean that some of the accounts have permission to perform certain state transformations to a vacation request.
The difference in modelling User/Manager/Employee as actors and roles is that you can focus on modelling what you need to put into the system, as don't have to have hierarchies of actors - you start using abstraction at the use case and system entity levels, rather than in the actors. It's not always a bad idea to think 'how would this work in code', at least as far as asking 'why bother coding this distinction'.