Can I set the record limit of Laravel's paginate method with user information? - laravel

I'm using the paginate method of the query builder and I would like to allow the user to choose the number of items per page.
$paginate= Model::paginate($request->input('per_page'));
Doing this could I be opening a loophole for SQL Injection or is this value sanitized first?

You can use a validator to make sure $request->input('per_page') is an integer or whatever validation you want.
documentation here : https://laravel.com/docs/9.x/validation

Such methods must be protected. This is what models are for.
But you are right, it's better to be safe than sorry and verify your premises. This is especially true with popular frameworks, because sometimes the creators crave for simplicity above everything else, often forgetting even security.
But it seems that in this case, Laravel QueryBuilder casts the perPage value to integer, making it immune to SQL injection:
protected function compileOffset(Builder $query, $offset)
{
return 'offset '.(int) $offset;
}
Then I dug a bit into the history, and found that the protection has been added almost a decade ago, so you can be sure that with any supported version of Laravel this part is safe.
That said, validating user input is still a good idea. Even being protected from SQL injections, you don't want any unexpected behavior. I don't think 500000 or -100 are good values whatsoever. If you can see that the data is not valid, it's a good strategy to bail off already, without waiting for some bizarre things to happen. So you may consider validating this input value just like any other input, like good programmers always do.

Related

Laravel 4.2 force mass assignment on createOrUpdate and similar methods?

I've been working on an API for awhile now that has a sort of 'soft' api validation so I can use Backbone more easily on the front end. Basically the design principal has always been to only validate and update the attributes sent back that we care about. On the backend, I use the model's fillable array to limit this after validating the input array. This way we don't have to annoy people when they accidentally send back model data that we don't allow them to touch as the docs clearly state whats fillable. People seem to enjoy working with the API.
What we run into is a problem because we want to use things like 'createOrUpdate' for our backend stuff that's creating or updating models automatically. Basically we end up adding things to fillable that go against our user facing input validation. Trudging around the docs I came across 'forceFill' and other various 'force' methods, but noticed that they are missing from the more magical methods like 'createOrUpdate'. Seems like they should be methods, or at least boolean flags that can be passed to the methods to force, and maybe these options are built into Laravel 5+?
Before I go ahead and write my own methods in the base, I just wanted to ask if this is already built into 4.2 and I'm just missing it? I also wanted to create this thread as it may be informative to people still confused by how Laravel's mass assignment works.
If I don't get any feedback I'll probably just delete it.
Model::unguard(); is added in 5.1 https://laravel.com/docs/5.1/seeding available in 4.2.
You just call it before you create the object, and then you can fill any fields using createOrUpdate(), firstOrNew(), create() etc.
Correction, here it is in the L4.2 API: https://laravel.com/api/4.2/Illuminate/Database/Eloquent/Model.html#method_unguard
see also: Model::reguard()

Laravel return values missing from documentation?

In the Laravel documentation, I can't find the possible return values are for basic Laravel functions like:
Mail::send(...) // does this return true/false if successful?
Input::get('foo') // what is returned when foo is not set?
Request::segment(2) // what is returned if there isn't a second segment?
Have I overlooked something or are we just left to trial/error to figure these out?
TL;DR
Take a look at the Laravel API website for all the source code. It's extremely well written and easy to follow. You should be able to answer all of these questions and learn new features very quickly.
=========================================
Laravel being as big and powerful as it is, makes it hard to document every little thing. However, using the API site, you can find answers to all these questions and discover TONS of neat, undocumented little tricks and treats.
Laravel API
Mail::send() Example
Take for instance your Mail::send() example. At the API site, we can search for Mail and browse to the Illuminate/Mail/Mailer.php page.
From there we can look at the code for the send() Line 94 method and see that it returns a call to $this->sendSwiftMessage($message).
From there, we can take a look at the code for the sendSwiftMessage() Line 281 method and see that it returns a call of $this->swift->send($message).
Looking through the Mail class, we learn that $this->swift is simply a instance of the Swift_Mailer class Line 56. The Laravel docs actually do mention that the Mail class is a wrapper for the popular Swift_Mailer.
Anyway, now we need to find what the send() method in the Swift_Mailer library returns. Where we see at the Swift_Mailer website, the send() method actually returns the number of recipients it was sent to, or 0 upon a failure.
Swift_Mailer itself actually have available quite a bit more useful
information, such as who the actual failed recipients were. However,
Laravel does not expose this information as of now. If you wanted to
gain access to Swift_Mailer's other features, you'd have to either
extend the Mail class or perhaps use the Swift_Mailer class
directly.
This essentially means, that yes, you can use a true/false check to determine success as 0 will evaluate to false and any positive, non zero number will evaluate to true in PHP. However, I also believe that Laravel will throw an exception if something goes wrong as it does in most cases, however this might be a, forgive the pun, exception where it will not throw an Exception.
Although that was a bit long winded, and probably one of the more complex examples. The vast majority of things Laravel provides are quick, easy to lookup and understand.
Going through the API is a great way to discover tons of undocumented features of the framework. For example, just go to the Str class and you'll see quite a few neat, useful things that you can use.
Input::get() Example
Without going into as much detail, Input::get ends up calling the array_get() helper function Link, which will return the following in order of priority.
The value stored at the key.
The default value passed to the Input::get() method.
null

Why is session data only available in the controller in CakePHP?

So, I like CakePHP and use it lots. When 2.0 came out, I was pleased to see the AuthComponent be made available throughout your whole application as a static class, which makes lots of things much easier - i.e. you no longer have to pass user data as an argument to model methods.
Recently on a project, I have perceived the need to access methods of the SessionComponent from a Model. Specifically, when a user logs in, some checks are performed to see if the user has a valid subscription to the site. This is all done in the model. If the user no longer has a valid subscription, there are a few reasons why that might be. It seems easiest to return false from the model, and at the same time set a flash message giving the reason for the expired subscription. Rather than return an array something like this:
array('status' => 0, 'message' => 'You\'re not welcome here anymore')
which needs interpreting in the controller.
There are other times I have wanted to deal with sessions in models, but this is the example that came to mind.
So, I'd like to know, am I right in wanting to access the SessionComponent in models? Should I just use $_SESSION directly when I have this need? Or am I doing things wrong - are there better ways to code?
you can always use
CakeSession::read()
anywhere in your application. so also in the model.
see previous posts like Reading a session variable inside a behavior in cakephp 2
but be adviced, that you should try to avoid it if possible.
models are supposed to be as stateless as possible - mixing them with sessions makes that more and more blurry.
According to CakePHP cookbook:
Usage of the $_SESSION is generally avoided in CakePHP, and instead
usage of the Session classes is preferred.
There are several different configurations where you can store session data, f.ex. in the database. So, by using CakeSession changes to session configuration will not affect every place where you access session data.
I would advice not to use SessionComponent from the model. Better pass parameters to the model with necessary data. Take a look at Understanding Model-View-Controller.
Passing session control to the Model violates MVC. You should use the model to make the decisions and the controller to reflect those decisions to the application. In a correct MVC enviroment the Model won't even know you are using sessions much less manipulating it.
Also, using the $_SESSION var violates the framework encapsulation. If you find yourself needing to do that, yes, you went wrong somewhere.
You can write and read data in session in model by using Authcomponent and session
App::uses('AuthComponent', 'Controller/Component');
App::import('Component', 'Session');
and you can write and read data using following functions
CakeSession::write('Auth.User.id', '1');
debug(CakeSession::read());

Yii framework: How do I use CActiveRecord.beforeFind()?

I'm in a need to use beforeFind() in a child class of CActiveRecord.
Basically, I need to convert some data from before actual search in the DB is performed.
How do I alter the about-to-occur-find-operation that is about to take place, inside beforeFind()? Messing with $this attributes is not useful since its not even populated, which is a little surprise.
I've seen that the documentation mentions a "hidden CDbCriteria parameter" but I just couldn't guess how to use it... . Unfortunately, the documentation on this subject is slim.
What I need to do is rather simple: I've got a table column for storing IP addresses. The most efficient design from scalability perspective, is to use a VARBINARY(16) data type for the column. See for example this SO question page (and answers) on this.
So, the cleanest solution would be to have beforeFind(), afterFind() and beforeSave() work transparently for the users.
In the code stack, the IP addresses would be the normal dotted-quad and in the DB level, its whatever that goes into the field after utilizing PHP's inet_pton() method in those after/before hook methods.
It was supposed to be cool. and it is cool - with afterFind() and beforeSave(), where I have the ip_address attribute of the object at hand, at the mercy of my uber-manipulation powers.
Here's the point, and the need: thing is, I don't know how to achieve that on beforeFind(). I cannot do a blind mergeWith() as I need to check if ip_address attribute is part of the original criteria, and that I don't know how to do.
Help!
TIA :)
I've got this nice suggestion on yii forums.
Basically, I just need to override findByAttributes() in the child class and I'm done :)

How to validate in domain layer

I often see people validating domain objects by creating rule objects which take in a delegate to perform the validation. Such as this example": http://www.codeproject.com/KB/cs/DelegateBusinessObjects.aspx
What I don't understand is how is this advantageous to say just making a method?
For example, in that particular article there is a method which creates delegates to check if the string is empty.
But is that not the same as simply having something like:
Bool validate()
{
Result = string.IsNullOrEmpty(name);
}
Why go through the trouble of making an object to hold the rule and defining the rule in a delegate when these rules are context sensitive and will likely not be shared. the exact same can be achieved with methods.
There are several reasons:
SRP - Single Responsibility Principle. An object should not be responsible for its own validation, it has its own responsibility and reasons to exist.
Additionally, when it comes to complex business rules, having them explicitly stated makes validation code easier to write and understand.
Business rules also tend to change quite a lot, more so than other domain objects, so separating them out helps with isolating the changes.
The example you have posted is too simple to benefit from a fully fledged validation object, but it is very handy one systems get large and validation rules become complex.
The obvious example here is a webapp: You fill in a form and click "submit". Some of your data is wrong. What happens?
Something throws an exception. Something (probably higher up) catches the exception and prints it (maybe you only catch UserInputInvalidExceptions, on the assumption that other exceptions should just be logged). You see the first thing that was wrong.
You write a validate() function. It says "no". What do you display to the user?
You write a validate() function which returns (or throws an exception with, or appends to) a list of messages. You display the messages... but wouldn't it be nice to group by field? Or to display it beside the field that was wrong? Do you use a list of tuple or a tuple of lists? How many lines do you want a rule to take up?
Encapsulating rules into an object lets you easily iterate over the rules and return the rules that were broken. You don't have to write boilerplate append-message-to-list code for every rule. You can stick broken rules next to the field that broke them.

Resources