I'm still pretty new to the grails framework and working on legacy application based on grails 2.
I have a domain controller allowing authenticated users to do all basic CRUD actions (create, read, update and delete), with "Read" including list and show.
I need to create another controller/view now allowing any user (non authenticated ones too) to be able to read only (list and show).
I looked around but could not find any "tuto" to do so ...then here's my question:
What would be the best approach to complete this task?
I looked into 2 options:
Option 1
Modifying the current domain controller (class level) #secured annotation in order to annotate only create, update and delete methods. I tried to do so, but it seems like I still have to authenticate which I suspect is related to SpringSecurity "grails.plugin.springsecurity.controllerAnnotations.staticRules" config that I may need to modify too.
Option 2
Create a new controller from scratch (but I guess I can't ask Grails to generate a second domain controller for the same class) then it means quite some work to build up all the data I need.
I'm not even sure if any of the 2 options above is recommended... has anyone faced this problematic (I'm sure many have) and if so ... what was the recommended approach?
Thanks.
I have a project that use the USER_ROLE to give access to different people to different parts of the project. But people still need to login.
I also have another project in C#. There is 2 copies of the same project. The public project is a copy of the main project. However, the public project is accessing the VIEWs set up from the database. It is not accessing the actual tables. So, the public project can have only read only access to a subset of the database records. It is only reading the VIEWs.
I am new to Grails. I don't know if you can set up the domain to access a view or not.
I am thinking outside the box. For your project, is it possible for you to create a new "public-read-only" project. Copy and paste the parts from the main project to the new "public-read-only" project that you want to give people to access.
In this case, your new project is a subset of the main project but it is accessing the records from the actual database tables.
What do you think?
Related
I am using ASP.NET WebAPI with the built in authentication and identity services that come with the Visual Studio template. I now have it that a user can access the system and be authenticated.
The next logical step is to allow the user to create records. Lets say the user can have a "Project". How can I associate the user with a project at the point the project is created? It seems logical that the project table will just store the user_id provided by User.Identity.GetUserId().
Now, say that a project consists of Tasks. By default the WebAPI will create a Tasks controller, where I post a task. I think I would need to inject some additional information (such as the project id) at the point of creating the task.
But, say someone wants to add a task a project that doesn't belong to them. I need to verify this by loading the project, and checking the user_id field. Now I am adding two repositories to my controller. This seems like a lot of work.
Is it my own laziness that makes this seem hard???
I think this might be a related question, as it seems like you are looking for record-level authorization.
MVC / ASP.Net Best Practice for Record-Level Authorization
There is merit also in using multiple repositories. See here for an example of use.
http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
Here, you would wrap the multiple repositories up within the UnitOfWork class.
I hope this points you in the right direction.
I'm using MVC 4.
I want to use the new SimpleMembershipProvider and stuff coming with it, however I can't get it work.
I've created a sample site by the tutorials, the Login/Register works as expected. I can create custom entities too with the new EF.
The problem is that I have multiple DbContexts in my case, one for the users (UsersContext) and one for my custom entities (MyCustomDbContext).
I want to add users as fields like Owner, Member etc. so I'd need to share the UserProfile data across the context. How should I do that?
Can I force the SimpleMembershipInitializer to use my custom DbContext?
EDIT: I'm using Code First approach.
I'm working on a project in Grails 2.0.RC1 and I'd like to be able to save the scaffolded controllers and views for my domain objects to have as a "low-level", developer only access to still tinker with things while being able to develop the production version of the views and controllers (with similar names, especially for controllers). I'd like to preserve them as-is, so I can re-generate them as I make updates to the domain layer, so just moving them is most likely not going to work.
I'm hoping there's a way to do some UrlMapping magic that would let me have requests for "/mgr/book" go to the scaffolded Book controller, but "/book" would go to my production controller. I can't find anything in the docs about how to have mappings for specific groups of controllers (without specifying each controller by name versus a $controller notation).
My other thought is to turn my domain layer into a plug-in and then create a separate project that would be just for the scaffolded views. This would be easier to remove before going to production, but also seems like more work, and raises the issue of running two grails apps at the same time on the same box.
I would advance you to go like your last idea. This is also my common approach:
Create an embeddable plugin for your domain model and common services. This also includes common plugins, like spring security and stuff. This will also reduce your dependency resolution time for the main-app btw.
Create an embeddable plugin for your scaffolded views. Change the template of the scaffolded controllers to require authentication and admin-group.
Your main-app uses both plugins.
This keeps your main-app clean and simple and you can still regenerate all your scaffolded views & controllers as you wish. And at least Eclipse STS hot-deployment will still work!
However there is no simple solution for seperating your scaffolded controllers URL-wise yet.
If you are using Spring Security, you should be able to use an InterceptUrlMap or RequestMap Instances to secure the controller URLs.
If your scaffold controllers are only used for scaffolding (and don't have other actions), then you should be able to use basic Secured annotations to secure the entire controller.
Then you can use the scaffolding like normal, protected behind a login.
Other security frameworks may provide similar access control.
I have a very tough problem for me to solve, and I thought and searched alot and came down t one conclusion which I will mention down.
the problem is I have a client that wants to create a websites based on a Common functionality, so let us call it Modules, so what I thought is to use MVC Contrib Portable Areas, which are great ideas to plug Modules, but I have a big problem, let us say I created a Blog module which will be implemented in a new site he want, now some users have unique requirements like one of them needs to add Gallery of pictures to each article, or List of references in each article.
this would be easy in normal situation where you have one site to work on, so all what you have to do is
add a new gallery table with Foreign key to the Blog table.
regenerate Linq2SQl code and update the Model.
add new form elements to the Create, Edit, Delete Views .
add the logic in the controller.
but in my situation it is complicated and time cumbersome because of 2 reasons
if the new functionality is cool
and client decide to implement it in
all sites, then I have to repeat the
work for each site.
if the functionality is unique it will create inconsistency for me in future
that is why as first step to solve the problem I used Portable Areas to create Addons for each Module, now this will definitely ease my work by dragging 1 DLL for each new Module or Addon, but I have a little problem here, which
because the new Module or Addin is a
Dll, how can I create such a
functionality in My Admin panel to
install the new Addon or find any new
added Module/Addon dragged new DLLS
to the Main Application
What is best
practice to create an installation
procedure inside the Portable Area,
like Update the DB, New Routes, etc..
Now to the biggest Problem which is specific to Module Addon :)
let us take back the Article Gallery Addon, if I follow the logic I have mentioned above by creating it as a Portable area, it would be easier to create a functionality in the Module Code to loop through all Installed Addons and list them in the CRUD Views, but because I isolated the Addon and don't want to manually update the Main Module Code for the Reasons Above there will be no way for doing CRUD operations for the new Addons in Sync with the main module because there is no Foreign Key Relation, again because as I said above it may be Optional, so I thought of the following solution which I hope there would be a better one
First in Installation Process I will create a Table for the Gallery Addon, but instead of creating a foreign Key relation I will create a manual Foreign Key which will get populated by Generating a Unique ID in the Main Module Controller when I create record by using the following code then store it in ViewData and just pass it to the Addon Controller when I create the new Record,
private string GenerateId()
{
long i = 1;
foreach (byte b in Guid.NewGuid().ToByteArray())
{
i *= ((int)b + 1);
}
return string.Format("{0:x}", i - DateTime.Now.Ticks);
}
ViewData["FK"] = GenerateId();
but here are my Concerns
Is this way feasible or just plain
Stupid.
is this technique will
generate a truly unique key.
I am extremely sorry if my question is lame, but this is the best place to ask and I think many people would want to have such a functionality and hope someone will answer me
I think it's a great question. awhile ago I started working on a CMS project using MVC1, where I wanted to support plugins. I had it working so that the admin could drop a new plugin assembly into the bin folder, and next app start, it would scan all assemblies for IPlugin (or whatever) and load them. I embedded the partial views into the plugin assembly so it was all self contained. each plugin was given a unique identifier when it was placed on a page, and the plugin's controller knew how to use that ID to query it's own table (repository) for it's data. the main application didn't know anything about the plugin's schema.
the only difference here is that it sounds like you would have multiple websites running on the same database, and you need to differentiate which instances of the plugin you need for each website. I assume somewhere you've got a key that indicates which website it is, that could be used via foreign key to select only the plugins for that website for the page the user is on.
I'm not sure if this is an answer, I'm sort of just thinking out loud. hopefully it'll help the discussion a little.
EDIT: To automatically load plugins, I used NInject's ability to scan assemblies for IModules. My IPlugin inherits from Ninject.Modules.INinjectModule, and all plugins implement the IPlugin interface. Then on app startup, I have the following line:
kernel.Load( "*.Plugin.dll" );
where kernel is a Ninject.IKernel and that line will scan any assembly matching that file pattern, so I could drop in an assembly like Weather.Plugin.dll.
We will be developing a very large vertical market web application, and are leaning toward the MVC approach.
It will have 1 Master Page common to all views in the application.
The master will provide a navigation/search framework for the entire application
that will allow users to search and select entities and then navigate to a function to perform.
The database model will have 700 to 1000 tables.
The application will have hundreds of controllers.
Controllers and their views could be grouped together into one of the many (20-50) subsystems in the application.
(We are looking at an areas approach to aide in organization).
We want to be able to deliver enhancements/updates in small functional pieces.
These might me a new function, a bug fix, customer dependent functionality, or optional modules separately purchased by the enduser.
We spent too many years developing/supporting and delivering one large windows vb app exe.
We would like to take another approach.
Management does not want to deliver one large application. They want to be able to deliver
small incremental pieces when necessary.
We may want to create a deliverable that contains one controller, and only a couple views, and a portion of the model.
To deliver it, we want to copy a dll to a bin folder, and create a View folder and copy in the new view(s). As simple as possible!
I have spent many days researching this and haven't come up with a clear path to proceed.
(Every tutorial and article I found assumed a single project.)
How do we structure the application to accomplish this?
How do we break up the application into separate projects/assemblies to do this?
Can you build a base project that contains the Master Page, authentication, and Global routing,
and then reference this in each of the potentially hundreds of other projects for each of the modules?
In development, does each sub-project need to contain the entire base project, or just the shared views folder, Global routing,
and web.config and a reference to the base project dll?
Any detail documents explaining this approach?
Any development/Testing issues?
Thanks for all input, we have to get this going soon.
Update:
Followed the example here link text
It is a great starting point!
I think this is exactly the case where DLR would help. Your Controllers and Views can be stored as scripts in the database. It will be very easy to deliver your application as a set of "small functional pieces". You could start from reading Haacked - Scripting ASP.NET MVC Views Stored In The Database
Absolutely, break the project up into sub-projects / modules containing your controllers. You can use an IoC container like Unity, Spring.Net, or Castle Windsor to locate your appropriate controllers in the child projects.
Implement your own IControllerFactory to do the Controller lookups in the IoC container based on the controller name passed to it. You're looking to put in place an IControllerFactory.CreateController method that looks something like:
public IController CreateController(RequestContext requestContext, string controllerName)
{
return (IController)IoCContainer.GetObjectByName(controllerName);
}
Then you should be able to simply modify your IoC configuration file to define your new controllers as they are deployed.
Google for MVC with MEF. There is an example by one of the MEF team that will suit your needs exactly.