Best way to control access to functions in CakePHP - cakephp

Simple question: what is the best way to ensure that a function is only being called from inside my app? I just want to make sure that nobody could just type in the url and run it.
I've thought about using Auth, but I really don't need username/password protection. Then I thought about private/protected functions, but I've read that CakePHP doesn't handle with that very well. And if I use private, as an example, I wouldn't be able to call the protected function from another controller class.
I think there must be a simply solution to this, but I can't think of one.
Thank you all in advance. :)

if you have functions that are been used in different controllers, it would be better if you create a component.
But.... if you really need to.. if you really want to.. you could set the access by adding an underscore at the beginning of your method's name:
class ProductsController extends AppController {
// a browser can "access" this method
function iHaveAView(){
}
// this method is used only by controllers
function _cantTouchMe(){
}
Good Luck
EDITED: (finally found the doc about this)
You can also change the visibility of controller methods in CakePHP by
prefixing controller method names with underscores. If a controller
method has been prefixed with an underscore, the method will not be
accessible directly from the web but is available for internal use.
source: Controller Conventions

I think it's simple don't put the function as an action of a controller. Create a component and use that when you need it.
That would make your function unavailable to the public but available within your app.
What do you think?

Related

Get current controller instance in UI-Router? (in tests)

I setup a test for a route based on this answer. I now want to check if things injected to the route's controller are setup correctly. From the state object, I can only get the controller's constructor function. I am wondering how can I access the actual instance?
This is probably way too roundabout to be the official solution, but it seems like it could work. If you use controller-as syntax in your state, i.e. "SomeController as ctrl", then it gets added to the $scope object with the given name. Afterwards, you can find this at:
$state.$current.locals['#viewname'].$scope.ctrl
...where '#viewname' would be the name of your view, and 'ctrl' is your controller alias.
There probably should be a simpler way to do this. It'd be a pretty handy feature for writing tests that span multiple states (without resorting to things like Protractor/Selenium)

Unit test private method

In typescript, what is the best way to test a private method. While testing a controller in Angularjs, sometimes controller add a property (function) to $scope, and if I do not make the property public, then assign to the $scope, I may to be able to test it. Is there a recommended way.
export class MyCtrl{
constructor($scope){
$scope.addProp = (d:string) => {
this.addProp();
}
}
private addProp(){
//...
}
}
One solution is to rearchitect your code so that it is more testable. You could create an AddPropProvider that does the actual work (with implementation details more exposed for testing) and pass it in to the constructor for MyCtrl. That's the classic inversion of control strategy.
Another solution is maybe just make that function public after all? Private is ideal for hiding implementation details that could change, but maybe you know that function is always going to be there anyways.
Finally there's the hack. That function really exists on the instances of MyCtrl and the compiler only doesn't want you calling it because you said so.
var m = new MyCtrl();
(<any>m).addProp();
Now if you remove or modify the signature for addProp that code will still compile so you've lost type safety. In most code that would be bad. But this is unit test code so we're going to learn about the break early and easily so it's not horrible.
One solution is to not use the scope as the strong glue to ui and only use it as a container for the controller class instance.this also has other advantages http://www.youtube.com/watch?v=WdtVn_8K17E
Then you can simply test your controller as you would test any other JavaScript class and not worry and $scope in your tests.
While I agree with Jeffery Grajkowski's solutions proposed above, there is one more option you should consider. Since JavaScript (and, by extension, TypeScript) doesn't have "real" private types, make it public, but private by convention.
That is, have the method name start with an underscore or "unitTest", so anyone who sees it will recognize that it shouldn't be used in production code.

Where is a good place to put a few small utility functions in AngularJS?

I have a very small number of functions that I need to use like this:
data-ng-disabled="_isEmpty(grid.view) || view != 'preview'"
What I did was:
$scope._isEmpty = _.isEmpty;
so that the _isEmpty is actually the lodash function.
Is this a reasonable thing to do? Also if so then where would be a good place for me
to code the above line? Should I code that in my appController. Also should I attach
the ._isEmpty to $scope or $rootscope? I have heard people talking about making a service and then injecting this. But for a few lines of code this seems overkill.
It all depends on where this code is required. If it is heavily reliant on, or required by a particular data object or view, then it most likely belongs in a controller. If inside a controller, $scope should be used by any value you want to reference in a view.
If however, you are writing generic functions used throughout your application, then they should be put in something like a service, and injected where required. Most of the time if you find yourself using $rootScope, the code should probably be in a service. Services aren't really overkill, as you can see below:
angular.module('myapp.services.something', [])
.factory('myService', [function () {
return {
myFunc: function (someArg) {
console.log(someArg);
}
};
}]);
You could put any number of generic helper functions for example in a service like this, and inject them into any controller that requires their use.
Though generally not recommended, I could see this kind of problem solved with putting the functions into the rootscope. Then putting the line $scope._isEmpty = _.isEmpty; in every controller would not be necessary anymore. A far better way for me would be to recode the utility functions into directives, even if involves some coding. Another way to solve the problem is to use services.

Angular docs: how can one share stateless/stateful code between controllers?

Been reading the Angular.js' Controller docs and stumbled across:
Sharing stateless or stateful code across Controllers — Use angular
services instead.
But this leaves me uncertain. How do one can share a stateless/stateful code between controllers? Or what does the "code" mean here? A model? Besides, controllers do not refer to each other, as far as I understood. Can anyone clear things out for me(others) please? Thanks.
I think what they are referring to might be one of the methods to "persist" data, sharing it between controllers or between route-changes. One way to do that is to put it in your rootScope, another is to use a service. If you define a service like this:
.factory("MyDataObject", function() {
return {};
})
Then MyDataObject will be the same object anywhere you call it, allowing you to save things into it in order to share data, functions and states between controllers (or directives, or other services, etc).
You never know with the Angular documentation, but I would guess that is what they are talking about :)
See for example this answer: Angularjs, passing scope between routes
Here is my view on subject. As angular guys have always tried to explain, scope is not your model. Angular "services" are way to do it, but word service is such and overloaded term. Coming from DDD background, I cannot reconcile word service with a state or statefulness, it just does not make sense to me. What makes more sense is ViewModel or whatever you want to call it. Since I've worked with Silverlight using MVVM pattern, I call them ViewModel. As it is a job of a "Controller" to provide Scope for a View, my controllers have been so far very lean. Bulk of logic is in a ViewModels that get associated with a View through a $scope that controller creates. Does that make sense? So my controller might take a dependency of let's say mySearchViewModel, bulk of the logic is in there and can be shared between controllers, and to associate it with a view you would do something like $scope.vm = mySearchViewModel in mySearchController.

Cakephp - Overriding model method from controller

I need to override & add methods in a model invoked by a controller. I don't want to write anything inside Model class file because it's used by other controllers too. Methods are like pagination() and find(), can I do it from inside a controller?
CakePHP behaviors are mixins. They add methods to a model, which is what you are looking for.
It sounds like dynamically attaching a behavior to the model would get you the outcome you need.
Looking at Model::__construct(), I can see that it calls $this->Behaviors->init($this->alias, $this->actsAs);.
You may be able to call it again after the model has been instantiated to attach different behaviors (ie. $this->MyModel->Behaviors->init('MyModel', array('MyBehavior'));).
In fact, a closer look reveals that $this->MyModel->Behaviors is an instance of BehaviorCollection. As such, you can use the attach() method.

Resources