Thymeleaf Swich with Spring Security - spring-security

I'm trying to build an eshop. I want to create a page that, when viewed by a User, only shows those items which quantity is greater than 0, but when Administrator viewing the same page, they can see all items and can add/edit/delete items regardless of whether the quantity is 0 or more.
I think maybe I can use Thymeleaf with Spring Security like this:
<div th:switch=sec:authorize="hasAuthority('admin')">
<div th:case="'admin'" class="tilt pic" id="whoKnows" >
<div th:case="'user'" class="tilt pic" th:unless="${viewAvailableWhisky.quantityWhisky} == 0">
but it's not working.
It's a joke? two people edit my text, but they don't know answer...

Two years later.
If you would want to stick to the th:switch approach, this could be a way:
<div th:switch="${#authorization.expression('hasAuthority(''ROLE_ADMIN'')')}">
<div th:case="true" class="tilt pic" id="whoKnows">ADMIN</div>
<div th:case="false" class="tilt pic"
th:unless="${viewAvailableWhisky.quantityWhisky} == 0">USER</div>
</div>

From http://www.thymeleaf.org/doc/articles/springsecurity.html:
The sec:authorize attribute renders its content when the attribute
expression is evaluated to true
Just use sec:authorize directly:
<div sec:authorize="hasAuthority('admin')" class="tilt pic" id="whoKnows"></div>
<div sec:authorize="hasAuthority('user')" class="tilt pic" th:unless="${viewAvailableWhisky.quantityWhisky} == 0"></div>
Your solution doesn't work because your switch condition will resolve to true or false but not to 'admin' or 'user'. hasAuthority('admin') will resolve to true if the user has the 'admin' authority and to false if not.

Related

Thymeleaf classappend for more than two alternatives

I have a badge used inside the bootstrap card. There are 3 possible values for this badge. FREE, BASE, PREMIUM.
I want to use different colors for these 3 values.
Div class looks like this:
<div class="badge text-white position-absolute" th:text="${content.getCategory()}"></div>
How can I update my class on the fly to use bg-dark for BASE, bg-primary for FREE, and bg-danger for PREMIUM?
I tried to use literal substitutions for th:classappend but I could not find a way to make it work with triple possible values.
You could do it like this:
<div class="badge text-white position-absolute"
th:with="category=${content.category.toString()}"
th:classappend="|${category == 'BASE' ? 'bg-dark' : ''}${category == 'FREE' ? 'bg-primary' : ''}${category == 'PREMIUM' ? 'bg-danger' : ''}|"
th:text="${category}"></div>
This also works by defining an inline map:
<div class="badge text-white position-absolute"
th:with="categoryClass=${ {'BASE': 'bg-dark', 'FREE': 'bg-primary', 'PREMIUM': 'bg-danger'} }"
th:classappend="${categoryClass.get(content.category.toString())}"
th:text="${content.category}"></div>

Check if .NET MVC Sitemap exists

I am using
<div class="row">
<div class="col-lg-12 breadcrumb" >
#Html.MvcSiteMap().SiteMapPath("")
</div>
</div>
to display the sitemap of current page. How do i check if the Sitemap exists for the Current page and then only display it?
like:
#if([Check Exists]){
<div class="row">
<div class="col-lg-12 breadcrumb" >
#Html.MvcSiteMap().SiteMapPath("")
</div>
</div>
}
By default, the SiteMapPath HTML helper already does this check. If there is no node that corresponds to the current request the SiteMap.CurrentNode property will be null. When that happens, no HTML will be output from the SiteMapPath HTML helper.
If that isn't good enough to cover your particular use case, you can use the built-in FilteredSiteMapNodeVisibilityProvider, a custom visibility provider, or security trimming to hide the nodes you don't want visible.
Failing that, you could create a custom partial view template for the SiteMapPath or create a custom HTML helper based on the SiteMapPath if nothing else meets your needs.

Clicking on the second of the two identical elements in capybara

I am writing the test automaton code for a system and the dev team presented me the following html:
<div id="someId">
<div class="classA">
<button class="classB">
</div>
<div class="classA">
<button class="classB">
</div>
</div>
Now the question is: Is it possible to click exclusively on the SECOND button? If so - how?
If I understand you right, you're click on links styled as buttons. You can use this step definition
Then(/^I click the (\d+) instance of link "(.*?)"$/) do |instance, link|
page.all('a', :text => "#{link}")[instance.to_i - 1].click
end
I would not rely on the order of elements returned by all. I remember running into issues with it in the past, see e.g. this issue. Instead I'd use a selector, something like this:
find("#someId div.classA:nth-child(1) button.classB").click
(IIRC they are zero-indexed)

Hide Content based on User Role?

I am currently developing a web app in Grails and I am looking for a way to hide a menu based on the current user logged into the solution.
To give you a bit of background this is what I have setup
A web app with a User Model and Roles model that are mapped
Login functionality that restricts certain controllers based on the users access.
I have menus that are display on each of the pages.
I know how to restrict a controller to only allow users with access to view it but I want to now restrict a menu like the one below from being seen unless the right user is logged in, how can I do this? Does it have something to do with rendering that element from the controller??
<div class="nav">
<ul class"nav">
<li>
<g:link class="Tester" controller="Testing" action="test">
<g:message code="Tester" args"[entityName]" />
</g:link>
</li>
<li>
<g:link class="Tester2" controller="Testing" action="test2">
<g:message code="Tester2" args"[entityName]" />
</g:link>
</li>
</ul>
</div>
The spring-security-core plugin provides a taglib that may help you here
<sec:ifAnyGranted roles="ROLE_TESTER">
<div class="nav">
...
</div>
</sec:ifAnyGranted>
Ian answered your question well but we should add here to secure the server side controller/actions as well such as:
// At the controller level
#Secured(["hasRole('User')"])
class Testing
// action specific
#Secured(["hasAnyRole('SuperUser', 'Support', 'InternalUser')"])
def test() {
...
}
Otherwise the links are just hidden from view but could still be executed by anyone.
HTH
If you are not using spring-security-core plugin following can be implemented
<g:if test="${userHaveRightRole}">
<div class="nav">
...
</div>
</g:if>

Inline if statement in grails

Is there a way in Grails to do conditionals inline on an HTML attribute, for example:
<div class="${if(sec.isLoggedIn()) loggedInClass}">
I'm trying to add a class to certain elements if the user is logged in.
This might work for you:
<div class="${(sec.isLoggedIn()?loggedInClass:null)}">
Or Try this:
<div class="${(sec.isLoggedIn()?'loggedInClass':'null')}">
You can do:
<div class="${sec.loggedIn ? 'loggedInClass' : ''}">

Resources