According to the Laravel Nova Website the release 3.10.0 has this new features:
Added new "standalone" actions for running actions without selecting resources. #961
Added ability for resources to auto-refresh their index listing. #957
The links to the pull requests, of course, don't work because this is no open source project.
I can't find anything in the docs about this new features. How to use them?
In your action class add the code below, to override the default value, set to false in /nova/src/Actions/Action.php.
/**
* Indicates if the action can be run without any models.
*
* #var bool
*/
public $standalone = true;
Related
I'm working on a project in 2017 Visual Studio CE utilizing .Net Core 2.0. I created an API directory for my Web API Controllers, and a Controllers directory for my standard MVC controllers.
I have a StoresController in each directory. The one in the API directory specifies the Route attribute as [Route("api/[controller]")]. The one in the Controllers directory does not have a Route attribute; it relies on the default routes set up in Startup.cs.
I created the following Delete link on my Edit view using the built-in tag helpers: <a asp-action="Delete" asp-controller="Stores" asp-route-id="#Model.Id" class="btn btn-danger">Delete</a>
For some reason this links to /api/stores/{id} instead of /stores/delete/{id}. Is there a way to configure the tag helpers to use the default MVC routes instead of the API routes? Or do I need to rename classes/action names?
Update: The Route attribute has an Order parameter that is supposed to affect the priority of the route when resolving requests. Changing this value did not affect the output of the tag helper.
You can add multiple routes to your control with an order, and anchor tag helper with use the first one.
[Route("[controller]/[action]", Order = 0)] // Same as default routes
[Route("api/[controller]/[action]", Order = 1)] // Your custom route
By default, all defined routes have an Order value of 0 and routes are
processed from lowest to highest.
It's late but for me it was the action names in StoresApiController. If you scaffold an API Controller using Visual Studio targeting .NET Core 2.2 (it might be the same as 2.0), it will generates actions with names that have Stores or Store as suffix:
// this works
public ActionResult GetStores() { ... }
public string GetStore(int id) { ... }
...
But I came from .NET Framework and I used to name my API methods without those suffixes:
// this doesn't work
public ActionResult Get() { ... }
public string Get(int id) { ... }
...
I changed all method names to what Visual Studio would generate for me (GetStores, PostStore, etc). It worked. I'm not sure why. It might be a bug or my little knowledge about routing, but here is the issue on Github.
I am working on a grails 2.3.8 project and trying to customize the Role Hierarchy. I am trying to change the default value of rolePrefix = 'ROLE_' in resources.groovy with rolePrefix = 'PERM_'. I understand that to make this work, I need to make the following changes in my Config.groovy into something like:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'tpo.core.acl.AdminAccount'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'tpo.core.acl.AdminAccountPermission'
grails.plugins.springsecurity.authority.className = 'tpo.core.acl.Permission'
And to establish hierarchy, I need to add this too in my Config.groovy
grails.plugins.springsecurity.roleHierarchy = '''
PERM_ACCOUNT_ALL > PERM_ACCOUNT_CREATE
PERM_ACCOUNT_ALL > PERM_ACCOUNT_READ
PERM_ACCOUNT_ALL > PERM_ACCOUNT_UPDATE
PERM_ACCOUNT_ALL > PERM_ACCOUNT_DELETE
'''
So in my Controller, it is something like,
#Secured(['PERM_ACCOUNT_ALL'])
def index() {
redirect(action: "list", params: params)
}
When I try to run my application, and access my controller's index() action, I was prompted to log in, this is expected because of the presence of #Secured(), but having successfully logged in, I was not yet able to access the index() action, and it displayed, Sorry, you're not authorized to view this page. The permission was assigned to the user that I used to logged in, but still, I was not able to access it.
Where am I missing?
There's a lot more to it than that :)
The reason that the plugin doesn't allow this change is to support the standard voters. Currently there are three styles of strings that can be used to specify access rules - role names, SPeL expressions, and the funky "IS_AUTHENTICATED" ones - IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_FULLY, and IS_AUTHENTICATED_REMEMBERED. Additionally there's a new way that was added for the 2.0 release - using a Closure and any arbitrary Groovy code inside of it, but that's unrelated to role names.
Each of the registered voters is queried to determine if they "support" (i.e. can vote on) each of these tokens. The logic is currently rather straightforward - the "IS_AUTHENTICATED_..." strings are handled by one voter, strings starting with "ROLE_" are handled by another, and everything else is assumed to be a SPeL expression.
To be honest, I think since roles would have to have been "registered" at startup anyway (to specify what access rules are allowed for each role in annotations, Config.groovy, etc.) that the role voter could do more than just check that the string starts with some prefix - it could look at its collection of known role names. So it probably wouldn't be too much work to add support for custom role prefixes for the 2.0 release, and I'll look into that. But for now, the plugin is as customizable as much as possible in every way except for this one exception.
I'm very new to Umbraco and have a requirement to set up a site where different customers will access the same site, but see it with their own brand. It must be the same site in IIS and re-using the same razor views and related code, but our business teams have a requirement to set up a new customer for the same site, with their own values for the configurable content data via Umbraco without relying on support or developer involvement.
eg. Site URL is www.mysite.com
Customer from ClientA visits (maybe via URL www.mysite.com/ClientA or perhaps www.mysite.com?brand=ClientA) and sees the version branded for them.
A customer from ClientB should be able to visit the same site but passing in their brand code instead and see their customized version.
My first question is: Is this acheivable? If so, what is the correct way to do it?
I want to maximise code re-use.
Any help or pointers would be hugely appreciated.
Thanks in advance.
You can do this is standard asp.net, add a code behind for the standard default.aspx page that umbraco uses to drive everything and then in the onpreinit event switch either the master page or theme to the correct branding; something like:
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
int templateId = umbraco.NodeFactory.Node.GetCurrent().template;
umbraco.template template = new umbraco.template(templateId);
string templateName = template.TemplateAlias;
if (Request.QueryString["brand"] = "ClientA")
{
Page.MasterPageFile = string.format("~/MasterPages/clienta/{0}.master", templateName);
}
}
So all content is tagged to the standard set of masterpages in the masterpages folder; but if a "?brand=ClientA" url is requested it automatically changes the masterpage to the clienta folder - allowing you to brand the page based on the querystring.
I'm currently developing a menu for my application that should be able to display only the controllers that the current user can access (requestmap defined in the database).
How can I check if the current user has access to a specific controller and action?
To check roles in view :
Spring security plugin provides ifAllGranted, ifAnyGranted, ifNoneGranted etc., tags to check roles
For example, to check Admin Role of logged in User :
<sec:ifLoggedIn>
<sec:ifAllGranted roles="ROLE_ADMIN">
Admin resource
</sec:ifAllGranted>
</sec:ifLoggedIn>
(tested in grails-2.2.2 and springSecurityCorePlugin-1.2.7.3)
org.grails.plugins.springsecurity.service.AuthenticateService authenticateService = new org.grails.plugins.springsecurity.service.AuthenticateService()
def isAdmin = authenticateService.ifAllGranted('ROLE_ADMIN')
if(isAdmin) {
println 'I am Admin'
}
This question is pretty old, but I thought I'd post at least an answer that seems to work with Grails 2.0. If you are using the spring security plugin, there's a tag lib included called grails.plugins.springsecurity.SecurityTagLib.
The tag-lib has a protected method, hasAccess() which can take the same params map that you give the g:link tag. So, if you extend SecurityTagLib, you can call hasAccess() and get the behavior you want. Why this isn't externalized into a service that can be injected is beyond me as the functionality seems to fulfill an obvious need.
We use this to wrap the g:link tag and only generate a link of the user has access to the target page:
def link = { attrs, body ->
if( hasAccess(attrs.clone(), "link") ) {
out << g.link(attrs, body)
}
else {
out << body()
}
}
When dealing with permissions in views and taglibs, you can use the AuthorizeTagLib that's provided by the plugin.
For example, if you don't want a menu item to appear in your list for unauthenticated users, you might use:
<g:isLoggedIn>
<li>Restricted Link</li>
</g:isLoggedIn>
If you have more specific roles defined and those roles are tied to your controller/action request mapping, you can use other tags, such as:
<g:ifAllGranted role="ROLE_ADMINISTRATOR">
<li>Administrator Link</li>
</g:ifAllGranted>
In my experience, there's not yet a good way to tie the request mapping to your markup - I think you're going to have to use some of the above tags to limit access to content within a particular GSP.
I think that Burt Beckwith has a future modification (and is currently providing a beta version) to the plugin that integrates some ACL stuff that might solve this problem better in the future, but for now, I think the best approach is a hybrid request map + GSP tags one.
Not sure of the situation when this question was originally asked, but now you can check to see if a user is in a specific role by using SpringSecurityUtils.ifAllGranted() which takes a single String which is a comma delimited list of roles. It will return true if the current user belongs to all of them.
if(SpringSecurityUtils.ifAllGranted('ROLE_ADMIN,ROLE_USER')) {
Obviously, you can simply pass one role to the function if that is all you need. SpringSecurityUtils also has methods like ifAnyGranted, ifNotGranted, etc, so it should work for whatever it is you are trying to accomplish.
SpringSecurityUtils is a static API, so you don't need to create a private member named springSecurityUtils or anything like that.
You have to configure the file config/SecurityConfig.groovy (if it does not exists, create it, this overrides the default Security Configuration)
Add this entry:
requestMapString = """\
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/=IS_AUTHENTICATED_REMEMBERED
/login/auth=IS_AUTHENTICATED_ANONYMOUSLY
/login/authajax=IS_AUTHENTICATED_ANONYMOUSLY
/login/authfail=IS_AUTHENTICATED_ANONYMOUSLY
/js/**=IS_AUTHENTICATED_ANONYMOUSLY
/css/**=IS_AUTHENTICATED_ANONYMOUSLY
/images/**=IS_AUTHENTICATED_ANONYMOUSLY
/plugins/**=IS_AUTHENTICATED_ANONYMOUSLY
/**=IS_AUTHENTICATED_REMEMBERED
"""
This is means that you have to log in to enter the site. But all the resources (css, js, images, etc) is accessed without authentification.
If you want specific role only enter specific controller:
For example, for UserController:
/user/**=ROLE_ADMIN
/role/**=ROLE_ADMIN
For more information: http://www.grails.org/AcegiSecurity+Plugin+-+Securing+URLs
Regards
As far as I can tell, there doesn't look like there's an easy way to do it.
You can inject an instance of the grails AuthenticatedVetoableDecisionManager which is a concrete class of spring's AbstractAccessDecisionManager by doing this:
def accessDecisionManager
This has a "decide" method on it that takes 3 parameters
decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
This is probably the method that you'd need to call and pass in the right things to figure out if the user with the auth creds can access that "object" (which looks like it's normally a request/response). Some additional digging around might prove out something workable here.
Short term, it's probably easier to use the ifAnyGranted taglib as another poster mentions.
I'm not sure about in Groovy, but in Java (so I assume Groovy too...) you could do (minus NPE checks):
GrantedAuthority[] authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
boolean isAdmin = false;
for(GrantedAuthority authority : authorities) {
String role = authority.getAuthority();
if(role != null && role.equals("ROLE_ADMIN")) {
isAdmin = true;
break;
}
}
As for knowing whether or not the action is supported, you'd have to call the RequestMap service to get the roles for the mapping and see if it contains the found user role.
We have a requirement to have our ASP.NET MVC websites be automatically closed down by a remote notification (change in database value). Where would be the best place to implement this?
Base Controller Class
Global.asax
Custom attribute
Other
Update
Lots of suggestions to use app_offline but this scenario will be happening daily and will be purely initiated by the database so I would rather have the application take the initiative rather than something external push the file in.
Also, I will probably need to redirect the users to a holding page (preferably an MVC controller method to keep everything consistent). I'm leaning more towards catching it in my BaseController and having that handle it
There's a standard way of "gracefully" terminating ASP.NET 2.0 webapp - just drop a App_Offline.htm to the root directory of your application. See this.
I would go with Global.asax Application_BeginRequest if you have to do it programmatically.
You could Response.Redirect the page to "Offline.aspx" which can retrieve a message from the database or whatever you need. Of course you'd have to look at the request to see if it was trying to get to "Offline.aspx" otherwise you'd end up in an infinite loop.
Or maybe all your applications can be redirected to a single website which would remove most the complication.
I'm going to answer this myself as I did it a different way but thanks to everyone for their responses.
What I ended up doing is overriding OnActionExecuting() in my BaseController class (which all my controllers derived from).
In this method I check the database (using a 1 minute cache) and if the website is closed I load up a view to display a closed message. Code shown below
Protected Overrides Sub OnActionExecuting(ByVal filterContext As System.Web.Mvc.ActionExecutingContext)
MyBase.OnActionExecuting(filterContext)
Dim _cfgService = ObjectFactory.GetInstance(Of IConfigService)()
If _cfgService.DynamicConfig.WebSiteClosed Then
filterContext.Result = ErrorHandler(_cfgService.DynamicConfig.WebSiteClosedTitle, _
_cfgService.DynamicConfig.WebSiteClosedMessage)
End If
End Sub
Handling this type of behavior in the Global.asax file sounds like the best solution and redirecting to a static "ofline/closed" page. Handle the request on the Application_BeginRequest method, check to see the the site is active, if it let it continue, if it is not online Response.Redirect the request to the static page.
protected void Application_BeginRequest(object sender, EventArgs e)
{
string redirectURL = "~/Offline.aspx"; //some static page
bool isOnline = false; //SQL Call, config value
if (!isOnline && !string.IsNullOrEmpty(redirectURL))
{
Response.RedirectLocation = redirectURL;
Response.End();
}
}
Sorry, don't know about ASP.NET, but in case helpful:
We have a single APPLICATION.ASP page for our site (CMS / Database merge type stuff); this is possibly not common and therefore may therefore restrict usefulness, but could perhaps be implemented by an INCLUDE at the top of all ASPX files
We rename APPLICATION.ASP to TEST.ASP and copy HOLDING_PAGE.ASP to APPLICATION.ASP
The HOLDING_PAGE.ASP is present in the WWW folder, so always ready-and-available. It contains a "Site not available" message etc. and is self contained for all CSS (no include files, no DB access). Only exception is the company logo (which is external to that file, obviously)
This method prevents all access to the site, is not dependant on having a working DB connection, and allows us to change anything on the site without interfering with the holding page (apart from Company Logo, but changing that is likely to be benign)
We can still access the site, internally, using TEST.ASP - so we can test any new rollout features before removing the holding page and putting the site live. If you want to prevent anonymous use of TEST.ASP then deny anonymous permission.
Remove holding page is: Delete APPLICATION.ASP (i.e. the holding page) and Rename TEST.ASP to APPLICATION.ASP
We also have a database flag that causes the normal APPLICATION.ASP page to show a holding page - which we can use whilst doing more minor changes.