Should FindUsersByName include partial matches? - asp.net

The MSDN documentation isn't precise on this point.
It says in one place: "Gets a collection of membership users where the user name contains the specified user name to match."
Later it says, "FindUsersByName returns a list of membership users where the user name matches the supplied usernameToMatch for the configured applicationName."
The SQLMembershipProvider supports wildcards, but the documentation doesn't say whether I must also do so with my custom membership provider.
Edit: I'm really asking more about the intent of the Membership Provider rather than what I should do in my specific situation.

The FindUsersByName function will do a match on the string you pass in.
If you want it to do a partial match then you need to add '%' on the end of the string you're searching for.

This sentence in the documentation explains it:
The SqlMembershipProvider performs its search using a LIKE clause against the usernameToMatch parameter. Any wildcards that are supported by SQL Server in LIKE clauses can be used in the usernameToMatch parameter value.
SO
"Gets a collection of membership users where the user name contains the specified user name to match."
is the accurate sentence if you do a search for "DAV*" you should get "Dave", "David, "Davis", etc.

Let's make it more restrictive (find exact match) to be sure that user 'joe' has no access to data of the user 'joel' :)
Anyway, do you really need to find a user given only part of it's name?
EDIT:
Now checked again the MSDN method you linked to, and it's name is FindUsersByName (users, not user) so the method is able to return more than one user. It this case I assume you should implement the code to return all matches.
If the method would be FindUserByName, then it is the opposite answer (you have the method GetUser for this)

Related

Check if a role is granted using a regular expression in Symfony2?

My roles are something like SEND_SMS_100, SEND_SMS_200 or more in general SEND_SMS_X where X is an integer. It's the maximum number of small text message that an user can send over a month. An user should have at max one of this role. I'm looking for:
ensure SEND_SMS_X is granted
extract X integer
AFAIK this will not support regular expression based search:
$this->get('security.context')->isGranted($roleName);
I think this is bad design - this shouldn't be something that is controlled by roles.
You should probably have a $smsPerMonth property on your user entity so you can call getSmsPerMonth() instead of using many different roles to figure out how many SMS messages a user can send.

Get Filtered List of users using Forms authentication

I am using forms authentication and need to get a list of users that have a certain role and have a certain value in a certain profile property. The way I am doing this is to call Membership.GetAllUsers and then looping through them and checking the roles and profile. Is there a better way to do this in 1 call so that I don't have to get all users back and iterate?
Thanks,
Sachin
You may use GetUsersInRole() method.
string []users=System.Web.Security.Roles.GetUsersInRole("role");
You might want to replace Membership.GetAllUsers with Roles.GetUsersInRole(string roleName) - at least you'll have less entries to check for your custom field value.

MVC3 routes - replace id with object name

I'm looking for a fast & elegant way of converting my object IDs with descriptive names, so that my autogenerated routes look like:
/products/oak-table-25x25-3-1
instead of
/products/5bd8c59c-fc37-40c3-bf79-dd30e79b55a5
In this sample:
uid = "5bd8c59c-fc37-40c3-bf79-dd30e79b55a5"
name = "Oak table (25x25) 3/1"
I don't even know how that feature could be named, so that I might google for it.
The problem that I see so far is the uniqueness of that "url-object-name", for example if I have two oak tables 25x35 in the db, and their names differ too little to be uniquely url-named but enough to fool the unique constraint in the db.
I'm thinking of writing that function for name-transform in SQL as an UDF, then adding a calculated field that returns it, then unique-constraining that field.
Is there some more mainstream way of achieving that?
One method is that employed by stackoverflow.com which in your case would be:
/products/5bd8c59c-fc37-40c3-bf79-dd30e79b55a5/oak-table-25x25-3-1
This ensures uniqueness, however the length of the UUID may be a deterrent. You may consider adding a sequential int or bigint identity value to the products table in addition to the uniqueidentifier field. This however would require an additional index on that column for lookup, though a similar index would be required for a Url having only a descritive string. Yet another method would be to use a hash value, seeded by date for instance, which you can compose with the descriptive name. It is simpler to rely on a sequential ID value generated by a database, but if you envision use NoSQL storage mechanisms in the future you may consider using an externally generated hash value to append.
Identity should have 2 properties: it should be unique and unchangable. If you can guarantee, that /products/oak-table-25x25-3-1 will never change to /products/oak-table-25x25-3-1-1 (remember, user can have bookmarks, that shouldn't return 404 statuscode)- you can use name as url parameter and get record by this parameter.
If you can't guarantee uniqueness or want to select record more faster - use next:
/products/123/oak-table-25x25-3-1 - get record by id (123)
/products/123/blablabla - should redirect to first, because blabla no exists or have anoher id
/products/123 - should redirect to first
And try to use more short identities - remember, that at web 2.0 url is a part of UI, and UI should be friendly.
MVC routing (actions) will handle spaces and slashes in a name. It will encode them as %20, and then decode them correctly.
Thus your URL would be /products/oak%20table%2025x25-3%2F1
I have done something very similar in an eCommerce platform I am working on.
The idea is that the URL without the unique ID is better for SEO but we didn't want the unique ID to be the product name that can change often.
The solution was to implement .NET MVC "URL slug only" functionality. The product manager creates "slugs" for every product that are unique and are assigned to products. These link to the product but the product ID and name can be changed whenever.
This allows:
domain.com/oak-table-25x25-3-1
to point to:
/products/5bd8c59c-fc37-40c3-bf79-dd30e79b55a5
(The same functionality can be used on categories too so domain.com/tables can point to domain.com/category/5b38c79c-f837-42c3-bh79-dd405479b15b5)
I have documented how I did this at:
http://makit.net/post/3380143142/dotnet-slug-only-urls

retrieve value from query string

I am integrating openid in my website.
I am able to retrieve data(ex email) from op provider(by query string).
But different op provider gives data in different key like gmail gives it under openid.ext1.value.alia2 key and yahoo gives it in under some different key.
how should i retrieve value from query string.
You must check namespaces. For example, the server may return openid.ns.ax = http://openid.net/srv/ax/1.0, and that would mean "everything that starts with openid.ax relates to the AX extension".
But it could be openid.ns.qwerty = http://openid.net/srv/ax/1.0 as well, and then everything that starts with openid.qwerty would be related to the extension.
Your code must read those namespaces and use aliases as defined by those. Read specifications for more information.

How do you achieve field level security in ASP.Net?

I have an .aspx form with 20 fields that must be disable based on a users role and a status of a order record. Currently the application has 5 roles and 3 status, so I have 300 different possible conditions that I have to account for.
My first thought is to store each permutation in a table, then set the fields when the page loads by looping through the fields. Is there a better way? Please note, I am using .Net 2.0 and NOT MVC.
I'd probably store the details of each field, and then the roles and status that can edit them, and do it that way.
What are the rules for the system? Basically, are there really 300 possible conditions? Or is that really certain fields are only editable for certain status, and then only certain roles can edit those fields? Or is it that certain fields are available for certain roles as well?
If it's more of the former I'd probably have something like this:
Three primary tables (makes it easy to extend if you add a field, role or status):
Fields
Roles
Status
Then two link tables:
Field.Id and Role.Id
Field.Id and Status.Id
Then for any given order and user you can then find which Fields are editable for the order's current status, and the users role, and as you work through the fields set the access rights appropriately - however you set the controls - either dynamically generating them based on the collection you get back, or statically on the page.
If you have an issue where the Role can override the Status, you could also store a boolean in the Field/Role table, indicating whether the Field should be avaiable regardless of status.
Like another responder, we also use a Business Object framework called CSLA. CSLA implements field-level security checks by requiring class developers to do security checks in the property get/set calls. A typical property implementation looks like this:
Private mFirstName As String = ""
Public Property FirstName() As String
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Get
CanReadProperty("FirstName", True)
Return mFirstName
End Get
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Set(ByVal value As String)
CanWriteProperty("FirstName", True)
If value Is Nothing Then value = ""
If Not mFirstName.Equals(value) Then
mFirstName = value
PropertyHasChanged("FirstName")
End If
End Set
End Property
Notice the calls to CanReadProperty and CanWriteProperty. The second parameter specifies that the method should throw an exception if the user is not authorized to perform the specific read/write operation.
The implementation of the CanReadProperty and CanWriteProperty are provided by the framework's base class but should be reproducible without adopting the entire CSLA framework. The implementations check an AuthorizationRules data structure which defines who is allowed/denied Read/Write access based on roles. Often, the AuthorizationRules structure is populated during object creation.
Exposing the same CanReadProperty and CanWriteProperty methods to your presentation-tier allows you to enable/disable UI elements based on the current user's access rights. For example:
FirstNameTextBox.ReadOnly = Not CanWriteProperty("FirstName", false)
Hopefully this information will provide you with a good starting point for developing your own implementation. If you're interested in learning more about CSLA then check out Expert C# 2008 Business Objects.
I suggest to use third party framework to achieve this. We use CSLA framework in our projects. It allow us to set authorization at field level.

Resources