How should you get correct id based on username for a user for a public profile view? - codeigniter

I'm trying to figure out how to view a profile-page in codeigniter. I know how to create templates and so on in CodeIgniter, but I don't know which way to go to handle "translation from username to userid" in a secure manner. This is a profile that should be viewed when the user isn't logged in (public profile).
Code snippet from my profile-controller:
$username = uri_segment(3); //Here's the actual username is stored in the url
$profile = new Profile();
$this->user_id = $profile->getUserByUserName($username);
Above seems ok, right? But when a username contains spaces, the "username-link" gets from "Gustav Wiberg" to "gustav-wiberg" (space replaced by hyphens, and the username is lowercase).
The actual link could look something like this: http://www.domain.com/profile/gustav-wiberg
But if I check this link with uri_segment I get username "gustav-wiberg" and not "Gustav Wiberg" which is the REAL username I want to compare with (by getting the return value of $profile->getUserByUserName($username);.
Am I taking the wrong approach to this? Or is it ok approach based on each username must be unique.
I could just do a replacement from uri_segment "gustav-wiberg" by capitalizing each word and replacing hypens with space and then do my query to check id for that username?
Please give me any pointers...

Either you can put a check while creating the username that there should not be spaces i.e. User can create a URL friendly username.
Or as you mentioned, you can do a replacement from uri_segment. But thinking of different scenarios, this approach can create issues so it seems its better to create a url friendly username.
One more option is you can add one more field in DB along with the username, say "slug". Wherein you can convert the username to URL friendly name and store. And check for that name while retrieving.

Related

Codeigniter search?

This project is something like a social networking site built on codeigniter.
Here my default controller is MyController.php (which loads the login page)
and say my domain is aravind.com
In my application each user will have a unique id.
and what my requirement is, the particular page of the user should get opened when
the unique_id of the user is given immedetily after the domain name.
ie, aravind.com/123 should open the user page whose unique id is 123.
I know this can be acheived by placing a controller and a function in between the
domain and the unique_id, (like : aravind.com/Search_class/search_func/123).
But by doing so the url of the particular user becomes lengthy which is not acceptable.
So I require a logic to sort this issue.
Note:
I have other classes and folders in my controller package, SO the required soln should be
wise enough to diferentiate my classes and folders in the controller package with the UniqueID.
So for differentiating I can say like the classes and folder name will be of continuous String
Where UniqueID starts with an underscore (_).
The same thing is done in facebook, like if we type facebook.com/aravind.pillai.983, it will open my account,
where as if the url goes like facebook.com/settings it will open the settings page for
the user who have an active session.
Set route["404_override"] to one of your custom class (say Search.php).
So wheneven a user tries to enter with an invalid url it will be redirected to Search.php.
Here using $this->uri->segment(1) you will get the value of the first uri segment.
You can write a logic there to identify whether the user entered a valid unique_id or not.
Now you got the uri value in one class (Search.php).
You should use routing where you can set every routes you want. In APPPATH.'config/routes.php' file add this:
$route['(:any)'] = 'Search_class/search_func/$1';
You should read documentation about routing and check other examples.
Also, pay attention that application will always check for Search_class/search_func/$1 in first URI segment so you need to put this rule at the end of routes.php file. Before that rule you need to set other rules like:
$route['about'] = 'pages_c/show/about';
$route['contact'] = 'pages_c/show/contact';
// then after all declared routes, you can set wild card placeholder
$route['(:any)'] = 'Search_class/search_func/$1';

Laravel unique user profile url like facebook

Assume I have a site with a unique URL for users, e.g. abc.com/user1.
I want users to be able to create their own user urls like abc.com/user1 to abc.com/foo
The problem here is that my site has static pages such as: about, help, contact, download.
On the profile page, when users change their url, i apply this validator to their new profile url:
'username' => 'required|alpha_dash|max:20|min:3|unique:users'
In this situation, if the user chooses their new profile url to the same as a Route of my app (help, about, download...), their URL looks like: abc.com/about, this is troublesome.
Of course, the Validator will return true because that name is valid: min=3, max=20 and unique in "users" table ( "users" table not contains any control, of course).
To solve this, I add name of some Route to "users" table (about,contact,download...), so they cannot make their profile URL like abc.com/about,
But this is not good idea, because I might add more Routes in future.
PS: I dont like URL like abc.com/profile/user1, must be abc.com/user1.
Please help me to solve this.
You can use Route::getRoutes() to get all registered routes in your application
$routes = Route::getRoutes();
foreach($routes as $route){
echo $route->getUri(); // getUri will return the url pattern it matches
}
Now you can use this to check if the username doesn't appear in your routes.
But be careful! If you want to add routes in when the application is running you will have to check everytime that there's no user that has taken the name you want to chose.
Here are some possibilities
1. Call static page routes first
You can either call the static routes first and then at the end you do a catchall like lukasgeiter suggested, or you might even do a check in the controller and go through your static pages first. The problem here is that the user can create the user (e.g. "about") but then when they call that page, they would see the about page, even though they've correctly created the username, this might create a confusion.
2. Blacklist
Another way would be to create a blacklist for these usernames, so that people can't even register these types of usernames (this would be similar to your solution of pre-creating those usernames, but this way would be a bit cleaner and more easily expandable). Using this you will always have the trouble that someone will have used the username, once you want to use it as a static page. E.g. when you want to expand into another country.
3. Static pages on one level lower
E.g. you can create the static pages one level lower, such as abc.com/static/about, so there would be no clash.
4. Prepend character before username
This is the way I went, because the other ways were technically a bit too risky for me. So I chose the '#' sign for my users. So abc.com/#ThisIsMe is my current solution. It works in different languages (as opposed to abc.com/profile/thisisme would only work in languages, where profile is the correct term)
I think Flickr went from flickr.com/username to flickr.com/photos/username. Google+ doesn't really let you decide, but makes suggestions (AND adds the +). Twitter and Facebook let users choose their own, I would assume they have a blacklist. LinkedIn uses /in/.

Using Additional Parameter in Unique Check for Angular Directive

So, I'm looking to create my first angular directive for a validation check. Essentially I want to ensure an user name is unique. This answer is perfect for my first pass, and works as expected for creating a new user.
I'd like this also to work for users who want to change their user name. On the server side, I would write code to check that the user name doesn't exist in the database for any user other than the current user. In other words, if a user is modifying their profile, and the form has a group of fields that include user name, I don't want to form to be invalid if the username already exists, since the reason it exists is that the current user already has it.
So what I would like to do is pass the userId (an integer PK) as a parameter in the ajax call in addition to the user name. The userId exists on the $scope, but I don't know how to modify the directive to allow me to pass additional information.
I would imagine the markup would look something like the following?
<input type="email" ng-model="userEmail"
name="userEmail" required unique-email="userId"/>
Since the uniqueEmail directive does not create a new scope, you can pass the name of the property as shown (unique-email="userId") and then use $eval in your link function:
var userId = scope.$eval(attrs.uniqueEmail);
Note that I'm assuming the link function parameter is named attrs (not attr).

Ensuring that only a particular user has access

If I want to protect an action for being accessed by everyone except one user, how do I do that?
So let's say a user has a product. When they go to the EditProduct action, how can I prevent anyone else from accessing it? In the past I always used User.Idenity.Name and compare dthat to their username. But if someone logs in as username instead of UserName then the case breaks even though it's the same user.
Using .ToUpper() or something like this on every check seems very flimsy and inefficient.
You can put an Authorize attribute above the action like this:
[Authorize(Users = "username")]
I'm not completely sure if it is case sensitive, but this is the best method for protecting actions and controllers. In addition, you can do the same with Roles:
[Authorize(Roles = "Administrator")]
String has a property for Equals:
User.Identity.Name.Equals("OtherName",StringComparison.CurrentCultureIgnoreCase)

How to convert a Blogger user name to numeric ID

When working with the Blogger API the user ID is expected to be numeric. I found out my numeric ID by looking at the URL for my Blogger profile page. However, I want my users to be able to use their usual Blogger user name. So:
Is there a way to convert Blogger
user names to numeric user IDs?
Is there a way to pass in user names
instead of IDs to the Blogger API?
Thanks!
It depends on what you are trying to do, but in most use cases you don't need to explicitly know this information because the authToken will take care of resolving these issues for you if you use the default URLs with the API. But, in the interest of providing an answer in case you really do need to know this:
After the user authenticates, just request some information, like the list of blogs, and you'll be able to extract the ID number from your choice of several places in the response.
Not really, except that during login you use the username. Otherwise you need to use either default, assuming an active authToken, or the ID to reference a particular user's Blogger content.

Resources