i have created small grails project now i wanns work on url mapping
my project name is Hellograils
path is localhost:8080/Hellograils
i created user authentication and registration using rest api
now i wanna display in url only root path except that no want to display any controller or action name
eg : localhost:8080/Hellograils/userlogin/passwordcheck
insteatd of this url that should display only root path
i.e localhost:8080/Hellograils
if its not possible that should display like localhost:8080/Hellograils/users its should take only one word after root path how can i solve this one
eg : localhost:8080/Hellograils/userlogin/passwordcheck insteatd of
this url that should display only root path i.e
localhost:8080/Hellograils if its not possible that should display
like localhost:8080/Hellograils/users its should take only one word
after root path how can i solve this one
If your context root is Hellograils and you want the passwordcheck action in the userlogin controller to be associated with localhost:8080/Hellograils then you can do something like this in your url mappings:
"/"(controller: 'userlogin', action: 'passwordcheck')
If you want localhost:8080/Hellograils/user to be associated with that same action, you can do something like this:
"/user"(controller: 'userlogin', action: 'passwordcheck')
All of that assumes your controller name is UserloginController and the action name is passwordcheck. More common convention is to use camel case so your controller name would be UserLoginController and the action name would be passwordCheck. If you do use those names, then in the mapping you would need to use userLogin and passwordCheck instead of userlogin and passwordcheck.
Related
In my project I have lot of endpoint views (APIViews, ViewSets). For all of them now I set permissions, some of them are default (e.g. AllowAny) and some are custom created:
permission_classes = (IsUserHaveSomePermission,)
Now I want to implement some flexible system, that will allow me to specify set of allowed endpoints for each user, for example:
On front-end I want to select some user and have a list of checkboxes that correspond to project's endpoints.
This is just an utopian solution, some details may be changed, but the main question is to how make something similar so that admins can basically dynamically change list of allowed endpoints/views for user?
thanks in advance
This solution can be implemented by storing if the user has permission to access the current request method and request path.
Create a new db model for storing the user, request method and request path. Lets say the name of the model is RequestPermission
Instead of the path you can store a constant representing the url so that you have the flexibility of editing the path later on. This constant can be the url name which is supported by django.
class RequestPermission(models.Model):
user = user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='request_permissions')
method = models.CharField(max_length=10)
path_name = models.CharField(max_length=200)
create a custom permission class:
class IsUserResuestAllowed(permissions.BasePermission):
def has_permission(self, request, view):
user = request.user
# you can choose how to get the path_name from the path
path_name = get_path_name(request.path)
return RequestPermission.objects.filter(user=user, method=request.method, path_name=path_name).exists()
Now you can use this class as the default permission class in rest framework settings or use it per view.
I have Swagger UI for API documentation, I use the same approach like in official specification for accessing it I use next URL:
http://localhost:9000/docs/swagger-ui/index.html?url=/assets/swagger.json
But I want to use http://localhost:9000/docs/ instead. I won't want to use WS for delegating, I would like to use single line in routes, like this:
GET /docs controllers.Assets.at(path:String="/public/lib/swagger-ui", file:String="index.html?url=/assets/swagger.json")
Or
GET /docs controllers.Assets.at(path:String="/public/lib/swagger-ui", file:String="index.html")
and http://localhost:9000/docs?url=/assets/swagger.json
What shold I change so it work?
You can't make shortness in route file for the URL /docs/swagger-ui/index.html?url=/assets/swagger.json because index.html is generated by swagger-ui plugin to public directory and requires access to files nearby (like js and css files). Play swagger-ui uses javascript for fetching json based description of your routes via URL parameter for further parsing this document to swagger-ui, in your case it's /assets/swagger.json endpoint.
I tried to make the mapping swagger's index.html file, so pass json location like URL parameter directly:
GET /swagger-ui controllers.Assets.at(path = "/public/lib/swagger-ui", file = "index.html")
Play couldn't render this page, and CSS wasn't found. I appended dummy mapping to every file in swagger's default directory /public/lib/swagger-ui:
GET /*file controllers.Assets.at(path = "/public/lib/swagger-ui", file)
Even after that Play couldn't properly render index.html.
How it can be solved without Play-Swagger:
Create directory public\swagger in your project;
Download all files from https://github.com/swagger-api/swagger-ui/tree/master/dist and copy them to public\swagger;
Copy your swagger.json (it's specification, right?) to public\specification;
Add to your routes file next line:
GET /docs
controllers.Assets.versioned(path="/public/specification", file: Asset
= "swagger.json")
I have created the sub routes from main route and I have created the subcontroller package e.g controllers.subcontrollers. Now how to access my sub routes from sub controllers.
You can access by using this:
// Redirect to /hello/Bob
def helloBob = Action {
Redirect(routes.Application.hello("Bob"))
}
As you can see in the playframework documentation.
https://playframework.com/documentation/2.3.x/ScalaRouting
But, if you meant that you have multiples controllers and divided them into packages and want to access them inside another another controller. You can achieve it using something like this:
controllers.packageName.routes.ControllerName.functionInsideController
Try to create a new route ex: subcontrollers.routes
main routes Ex:
-> /subcontrollers subcontrollers.Routes
subcontrollers.routes Ex:
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.subcontrollers.Assets.at(path="/public", file)
GET /example controllers.subcontrollers.SubController.sample(parameter1:Long,parameter2: String)
Reference Link
I am wondering how should I structure my ACL for CRUD with Parent/Child Relations.
Eg. Projects have TodoLists. TodoLists have Todos
There are various controller actions for project
/projects/add
/projects/edit/{projId}
/projects/delete/{projId}
/todo-lists/add/{projId}
/todo-lists/edit/{todoListId}
...
As you can see going down the hierarchy, some actions have ids that refer not to themselves (eg. todo-lists controller -> todo-list resource) but to their parent
So with with I have setup (generally), it looks like this
ACL Controller Plugin (preDispatch)
Set role to loggedin user or 'unauthenticated'
Set resource to controller name
Set privilege to action name
if request param 'id' is set, get the actual entity (I am using Doctrine ORM) that implements Zend_Acl_Resource_Interface. Here is where the complication arises. I will usually get the resource from the controller name, but for eg. with /todo-lists/add I must know to get the parent entity instead (Project). With this setup, I will have to chage the privilege to to something like 'addTodoList'. This way, the project acl assertion class will have to TodoLists stuff. There will also be a disconnect between Controller Actions & ACL Logic. Is that ok?
Maybe I should have addTodoListAction in ProjectsController instead of TodoListsController? This will simplify my ACL code, I won't need to check and modify resource/privileges? I can just take these directly from the request params (Controller & Action names).
How do you setup ACL's like this?
use Zend_Acl_Assertion , create your assertion for projectid and todoId. At the time of giving permission do
$myAcl->allow($role,'projects','edits',new My_Project_Assertion());
and you cannot use action "addTodoListAction" because of captial letters (or define your own dispatcher) addtodolistAction wd work;
specifically, the default directory naming structure is [Controller]/[ActionMethod] resulting in a rendered url like www.mysite.com/home/actionMethodName.
What if I want to simply imply the Controller (in this example, 'home') so that I can get a url that looks like this: www.mysite.com/actionMethodName.
I haven't seen many requests for this kind of configuration. I can see how it breaks convention, but I would imagine that there are lots of people who need root pathing.
Because you are planning to remove the {controller} element of the url, you may need to get a bit more specific with your other urls, e.g.:
routes.MapRoute("MyOtherControllerRoute", "Account/{action}", new { controller = "Account", action = "Index" });
routes.MapRoute("MyDefaultRoute", "{action}", new { controller = "Home", action = "Index" });
When the route table is interrogated, if the url such as www.mysite.com/Account is used, it will match the first route, because we have been specific about the pattern used to match the url. If we then do something like www.mysite.com/DoSomething it will use the default route we've selected last, trying to invoke the DoSomething action on the HomeController type.
Something which I've noticed is that a lot of MVC developers seems to assume that the url is strictly {something}/{something}/{something}, whereas it can essentially be anything you like, e.g, I can have a route that does: www.mysite.com/my-weird-and-wonderful-url which I could map specifically:
routes.MapRoute("Somewhere", "my-weird-and-wonderful-url", new { controller = "Whatever", action = "Whenever" });
Hope that helps.
Easy as apple pie - you just specify a route of your own! =)
An example:
routes.MapRoute(
"RootPathing",
"{action}",
new { controller = "Default", action = "Index" });
This will register a route that catches all paths, and try to map them to the DefaultController with an action name corresponding to the path. However, note that if you place this route above the included default route, you will not be able to reach any other controller than the DefaultController - hence, place this route below the default route in the chain. It will then be matched by all paths that don't match a controller name.
When debugging routes, Phil Haack's Routing Debugger is really worth taking a look at.