Spring security with dynamic privilege checking - spring-security

<div xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.w3.org/1999/xhtml">
<span sec:authorize="hasAnyRole(${p})">
<button>Save</button>
</span>
</div>
I have this code for checking the privilege of accessing the save button.
model.addAttribute("p", p); added at the controller with p as comma separated privileges. So how do I check user has any of the given roles.

Please consider using Preprocessing feature. You can do it as follows:
<div xmlns:th="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.w3.org/1999/xhtml">
<span sec:authorize="hasAnyRole(__${p}__)">
<button>Save</button>
</span>
</div>
Note the use of double underscore beginning and end characters in which thymeleaf evaluates this expression before anything else.

Related

How to avoid empty <div> tags from th:if in Thymeleaf?

<div th:if="${user.admin}">
Welcome, Admin
</div>
Above code leaves an empty tag in the document if the user is admin. These empty divs creating alignment problems, how to avoid this?
You can achieve this by using th:block instead of <div> for conditional display.
<th:block th:if="${user.admin}">
Welcome, Admin
</th:block>
courtesy : https://anshulgnit.blogspot.com/2019/10/th-block-tag-in-thymeleaf.html

th:with what is the difference between the two examples

<p th:with="firstName1='James1'">
<p>Upper</p><p th:text="${firstName1}"></p>
</p>
<p th:with="df='today'">
Today is: <span th:text="${df}">13 February 2011</span>
Could you tell me what is the difference between the two code sections. They seem identical for me. But there is some difference as the results differ.
Alright, I've never encountered this before... but it looks like Thymeleaf is enforcing the rule that Any <p> (or other block-level element) will implicitly close any open <p>. This works, for example:
<div th:with="firstName1='James1'">
<p>Upper</p>
<p th:text="${firstName1}"></p>
</div>
<p th:with="df='today'">
Today is: <span th:text="${df}">13 February 2011</span>
</p>
In your example, the firstName1 variable is out of scope because the parser is treating your HTML like this (so firstName1 is considered null):
<p th:with="firstName1='James1'"></p>
<p>Upper</p>
<p th:text="${firstName1}"></p>

Rails: Bootstrap Accordion not collapsing

Here's my code:
<div class="panel-group" id="accordion">
<% #workspace_tasks.each do |t, a| %>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<%= t.to_s %>">
<%= t %>
</a>
</h4>
</div>
<div id="collapse<%= t.to_s %>" class="panel-collapse">
<div class="panel-body">
<table class="table table-striped">
</table>
</div>
</div>
</div>
<% end %>
</div>
As you can see, I am setting the ID for the panel to be in line with the Key for the hash which I am looping through.
The information is displayed correctly, however, if I set the panel by default to be expanded, I cannot collapse it. The inverse is true too where I cannot expand the panel if I set to to collapsed by default.
I us identical code elsewhere in my app but with a different Model being used to create the hash in the Controller. I find this behavior very strange.
I'm not sure whether it is my code? Or something with Bootstrap?
The HTML5 specifcation states that id cannot contain spaces:
When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element’s tree and must contain at least one character. The value must not contain any space characters.
You need to prepare t variable to be a valid id, e.g. by replacing spaces with -:
t.to_s.gsub(/\s/, '-')
Or by using parameterize:
t.to_s.parameterize

Setting Data-Parent and HREF dynamically in a for-loop

Previously to create Accordion controls I used to use this piece of code:
<div class="panel-group" id="accordionMessagesSetup">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordionMessagesSetup" href="#collapseMessagesSetup">
<span class="glyphicon glyphicon-chevron-up"></span>
Message Setup
</a>
</h4>
</div>
<div id="collapseMessagesSetup" class="panel-collapse collapse in">
<div>
<p style="background-color: red"> Someting ELSE in here</p>
<p style="background-color: red"> Someting ELSE2 in here</p>
</div>
</div>
</div>
</div>
or as seen here: Bootplay Live Demo
Now I still want to use my example but in this page I have a for-each loop so I need to create these at run-time.
The items I need to put variables there in order for this to work are
id="accordionMessagesSetup"
data-parent="#accordionMessagesSetup"
href="#collapseMessagesSetup"
id="collapseMessagesSetup"
How can I initialize those in a for-each loop a mode using Razor?
Imagine you have whatever property you like to do it in the model.
The biggest issue you are/will likely run into is Razor parsing. When you try to use a Razor variable in the middle of some bit of text, often Razor cannot determine where the variable name ends. For example, if you were to do something like:
<div id="accordion#Model.IdMessageSetup">
Razor thinks it needs to look for a property on the model named IdMessageSetup, when actually, you just wanted Id. The easiest way to fix this is to wrap the variable in paranthesis:
<div id="accordion#(Model.Id)MessageSetup">
Now, it's clear which part is the variable. As far as adding the # sign goes, I'm not really sure what the confusion is there. You just put it where it needs to go:
<a href="#collapse#(Model.Id)MessagesSetup">
Nothing special required.

Difference between Thymeleaf include and replace?

What is the difference between the two Thymeleaf attributes: th:include and th:replace?
According to documentation if you have this situation:
<div th:include="..."> content here </div>
fragment will be placed inside <div> tag.
However when you use replace:
<div th:replace="..."> content here </div>
then <div> will be replaced by content.
Thymeleaf can include parts of other pages as fragments (whereas JSP
only includes complete pages) using th:include (will include the
contents of the fragment into its host tag) or th:replace (will
actually substitute the host tag by the fragment’s).
Taken from baeldung
There are three basic ways to include content from a fragment:
insert – inserts content inside the tag
replace – replaces the current tag with the tag defining the fragment
include – this is deprecated but it may still appear in a legacy code
Try to understand with this
suppose this the fragment
<div th:fragment="targetFragmentToIncludeInOurPage" id="tagWithFragmentAttribute">
<div id="contentGoesHere"></div>
</div>
we are using this in these div
<div id="tagWithReplaceAttribute" th:replace="fragments/header :: targetFragmentToIncludeInOurPage"></div>
<div id="tagWithInsertAttribute" th:insert="fragments/header :: targetFragmentToIncludeInOurPage"></div>
<div id="tagWithIncludeAttribute" th:include="fragments/header :: targetFragmentToIncludeInOurPage"></div>
So the final output:
<div id="tagWithFragmentAttribute">
<div id="contentGoesHere"></div>
</div>
<div id="tagWithInsertAttribute">
<div id="tagWithFragmentAttribute">
<div id="contentGoesHere"></div>
</div>
</div>
<div id="tagWithIncludeAttribute">
<div id="contentGoesHere"></div>
</div>
Thymeleaf can include parts of other pages as fragments (whereas JSP only includes complete pages) using th:include (will include the contents of the fragment into its host tag) or th:replace (will actually substitute the host tag by the fragment’s). This allows the grouping of fragments into one or several pages.

Resources