PrettyFaces and Rewrite libraries - how can we call a bean method before PrettyFaces sets attributes from URL query parameters? - prettyfaces

We use Prettyfaces and Rewrite library in our JSF project.
Is there a way how we can reset bean attributes (set them to null) before PrettyFaces sets these attributes' values from query parameters in the URL?
I.e. can we call a method on the bean before PrettyFaces sets the values?

To accomplish this, I believe the simplest way would be to Inject the Bean into a RewriteConfiguration object. You'll need to make sure the priority is overridden such that this provider occurs before the built-in PrettyFaces functionality (I believe -10 should do, but you may need to play with this value):
public class ExampleConfigurationProvider extends HttpConfigurationProvider
{
#Inject
private MySessionBean bean;
#Override
public int priority()
{
return -10;
}
#Override
public Configuration getConfiguration(final ServletContext context)
{
return ConfigurationBuilder.begin()
.addRule()
.when(Path.matches("/my-path").and(Direction.isInbound()))
.perform(new HttpOperation() {
#Override
public void performHttp(HttpServletRewrite event, EvaluationContext context)
{
bean.clearValues();
}
});
}
}
```
Note, the .when() rule can contain any conditions that you want.
There are probably other ways of doing this, but this is the simplest I could think of.

Related

spring boot - why is #valid not working on controller for type?

I have Spring Boot application with a rest endpoint in a #RestController annotated class that is something like this:
#Postmapping(path = "<url>")
private #ResponseBody ResponseEntity<?> methodName(
otherParameters otherParameters,
#Valid #RequestBody Entity entity,
Errors errors) {
if(errors.hasErrors()) {
// log something
// do something
}
// rest of the controller
}
The Entity class is something like this:
public class Entity {
#Pattern(regexp = "[^<>&]+")
private String someString;
// getters and setters
}
But when I try to reach the controller with someString as some&tring, the #Valid annotation does not seem to work.
This is accessible only from a rest call. There are no forms that use this action.
There is no spring-security implementation in this application at the moment.
What am I missing here?
Be sure to add #Valid on the member fields of your pojos if those fields represent pojo's themselves, otherwise the validation does not propagate.
I think you are missing the object add to the page.
check the following code.
check 1 :
// on controller side
#GetMapping("/registration")
public String registration(Model model) {
model.addAttribute("entity", new Entity());
return "registration";
}
#PostMapping("/registration")
public String registration(#ModelAttribute("entity") Entity entity, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "registration"; // stay on that page here
}
return "login"; // after no error go here
}
use this entity in form on the page where you want to access the validation
<form action="#" th:action="#{/registration}" th:object="${entity}" method="post" class="m-t">
check 2 :
both the get and post method must be the same name for the object created like **entity**

Is it possible to Mock and ignore properties

I'm changing our identity strategy and we're using an ID that is generated before the Entity is written to the database. This change is causing some of our tests to fail due to the way we're mocking some service calls.
TimeLog timeLog = buildTimeLog('123456', mockEmployeeId);
TimeLog mockTimeLog = buildTimeLog('123456', mockEmployeeId);
when(this.timeLogService.save(mockTimeLog)).thenReturn(timeLog);
When the test makes the call to the Controller, the bound entity in the Controller gets a different ID than the mock that is expected because the Entity generates the ID. Whereas before, the database generated the ID so the mocks worked.
If there is a way to tell Mockito to ignore a property in the expectation? That would solve the problem and the test would still be valid. Otherwise, other approaches are welcome.
You can't tell mockito to ignore a property in an expectation because it's using the java "equals" method... You can define an equals method in TimeLog that igonres ID but I suspect that won't give you what you want. The other approach is, instead of trying to tell mockito what not to verify, define explicitly what it is to verify using a hamcrest matcher. Define a hamcrest matcher which just matches the fields you want to verify i.e. all fields other than ID. So something like:
private class TimeLogMatcher extends TypeSafeMatcher<TimeLog> {
private final EmployeeId employeeId;
public TimeLogMatcher(EmployeeId employeeId) {
this.employeeId = employeeId;
}
#Override
public void describeTo(Description description) {
description.appendText("TimeLog with employeeId=" + employeeId);
}
#Override
public boolean matchesSafely(TimeLog item) {
return employeeId.equals(item.getEmployeeId());
}
}
And then instead of calling whatever your "buildTimeLog" method is doing call into the mockito Matchers class like:
TimeLog timeLog = Matchers.argThat(new TimeLogMatcher(mockEmployeeId));
Or alternatively you could always use an Answer object:
when(this.timeLogService.save(any(TimeLog.class)).thenAnswer(new Answer<TimeLog> {
public TimeLog answer(InvocationOnMock invocation) throws Throwable {
TimeLog receivedTimeLog = invocation.getArgumentAt(0, TimeLog.class);
assertThat(receivedTimeLog.getEmployeeId(), equalTo(mockEmployeeId));
return timeLog;
}
});
Does that all make sense?

ServiceStack: Routes.AddFromAssembly still uses /json/reply path and no URL-niceness for properties

I have a ServiceStack self-hosted webservice, using the AppSelfHostBase.
WHen the Configure method is executed, I have this:
public override void Configure(Container container)
{
Config.RouteNamingConventions = new List<RouteNamingConventionDelegate> {
RouteNamingConvention.WithRequestDtoName,
RouteNamingConvention.WithMatchingAttributes,
RouteNamingConvention.WithMatchingPropertyNames,
};
Routes.AddFromAssembly(typeof(ServiceStackHost).Assembly);
and I expected the following service to be executed under /StartBankIdAuthentication path, but it resides under /json/reply/StartBankIdAuthentication instead.
public class StartBankIdAuthentication : IReturn<StartBankIdAuthenticationResponse>
{
public string IdNbr { get; set; }
}
Also, is there an automatic way to make the properties in the DTO to be under "sub-paths", like /StartBankIdAuthentication/1234 instead of the /StartBankIdAuthentication?IdNbr=1234?
I know I can manually add the Route attribute, but it seems cumbersome and also messy in many ways (not Typed, error-prone etc).
I expected the following service to be executed under /StartBankIdAuthentication path, but it resides under /json/reply/StartBankIdAuthentication instead.
The /json/reply/StartBankIdAuthentication is a pre-defined route that's always available by default, they have no relation to Auto Generated Routes.
The default Route generation strategies you've listed are already registered by default and are what's applied when you use Routes.AddFromAssembly(). You should only override with route strategies you want in addition to the defaults, and you should use SetConfig() for any configuration in ServiceStack, e.g:
SetConfig(new HostConfig {
RouteNamingConventions = { MyCustomRouteStrategy }
});
The implementation for the different Route Strategies available in ServiceStack are in RouteNamingConvention.cs, you'll need to register your own strategy for anything additional Route strategies you want.
By default additional routes are generated for any Id or IDs property, the routing docs shows examples of how they can be customized:
The existing rules can be further customized by modifying the related static properties, e.g:
RouteNamingConvention.PropertyNamesToMatch.Add("UniqueId");
RouteNamingConvention.AttributeNamesToMatch.Add("DefaultIdAttribute");
Which will make these request DTOs:
class MyRequest1
{
public UniqueId { get; set;}
}
class MyRequest2
{
[DefaultId]
public CustomId { get; set;}
}
Generate the following routes:
/myrequest1
/myrequest1/{UniqueId}
/myrequest2
/myrequest2/{CustomId}
I know I can manually add the Route attribute, but it seems cumbersome and also messy in many ways (not Typed, error-prone etc).
If you really want you can use nameof() for Typed Routes:
[Route("/" + nameof(StartBankAuthentication) +"/"+ nameof(StartBankAuthentication.IdNbr))]
I'm not sure if Mythz will maybe come up with a different of better solution, but I managed to achieve what I wanted by overriding the GetRouteAttributes, and by using reflection, I could create what I wanted. It looks like this:
public override RouteAttribute[] GetRouteAttributes(Type requestType)
{
string fullname = requestType.FullName.Replace("AlfaOnlineServiceModel.Api.", "");
string path = "/" + fullname.ToLower().Replace(".", "/");
RouteAttribute[] routes = base.GetRouteAttributes(requestType);
if (routes.Length == 0)
{
routes = new RouteAttribute[1];
PropertyInfo[] pInfos = requestType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
foreach(PropertyInfo pi in pInfos)
{
path += "/{" + pi.Name + "}";
}
routes[0] = new RouteAttribute(path);
}
return routes;
}
Which will give for example:
MyMethodResult
The following routes are available for this service:
All Verbs /myCoolPath/mySubPath/myMethod/{MyProperty}

using a Singleton to pass credentials in a multi-tenant application a code smell?

I'm currently working on a multi-tenant application that employs Shared DB/Shared Schema approach. IOW, we enforce tenant data segregation by defining a TenantID column on all tables. By convention, all SQL reads/writes must include a Where TenantID = '?' clause. Not an ideal solution, but hindsight is 20/20.
Anyway, since virtually every page/workflow in our app must display tenant specific data, I made the (poor) decision at the project's outset to employ a Singleton to encapsulate the current user credentials (i.e. TenantID and UserID). My thinking at the time was that I didn't want to add a TenantID parameter to each and every method signature in my Data layer.
Here's what the basic pseudo-code looks like:
public class UserIdentity
{
public UserIdentity(int tenantID, int userID)
{
TenantID = tenantID;
UserID = userID;
}
public int TenantID { get; private set; }
public int UserID { get; private set; }
}
public class AuthenticationModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.AuthenticateRequest +=
new EventHandler(context_AuthenticateRequest);
}
private void context_AuthenticateRequest(object sender, EventArgs e)
{
var userIdentity = _authenticationService.AuthenticateUser(sender);
if (userIdentity == null)
{
//authentication failed, so redirect to login page, etc
}
else
{
//put the userIdentity into the HttpContext object so that
//its only valid for the lifetime of a single request
HttpContext.Current.Items["UserIdentity"] = userIdentity;
}
}
}
public static class CurrentUser
{
public static UserIdentity Instance
{
get { return HttpContext.Current.Items["UserIdentity"]; }
}
}
public class WidgetRepository: IWidgetRepository{
public IEnumerable<Widget> ListWidgets(){
var tenantId = CurrentUser.Instance.TenantID;
//call sproc with tenantId parameter
}
}
As you can see, there are several code smells here. This is a singleton, so it's already not unit test friendly. On top of that you have a very tight-coupling between CurrentUser and the HttpContext object. By extension, this also means that I have a reference to System.Web in my Data layer (shudder).
I want to pay down some technical debt this sprint by getting rid of this singleton for the reasons mentioned above. I have a few thoughts on what a better implementation might be, but if anyone has any guidance or lessons learned they could share, I would be much obliged.
CurrentUser isn't quite a singleton. I'm not exactly sure what you'd call it. (A singleton by definition can only exist one at a time, and any number of UserIdentity instances can be created at will by outside code and coexist without any issues.)
Personally, i'd take CurrentUser.Instance and either move it to UserIdentity.CurrentUser, or put it together with whatever similar "get the global instance" methods and properties you have. Gets rid of the CurrentUser class, at least. While you're at it, make the property settable at the same place -- it's already settable, just in an way that (1) would look like magic if the two classes weren't shown right next to each other, and (2) makes changing how the current user identity is set later harder.
Doesn't get rid of the global, but you're not really gonna get around that without passing the UserIdentity to every function that needs it.

Moq custom IIdentity

I created a custom RoleProvider (standard webforms, no mvc) and I would like to test it. The provider itself integrates with a custom implementation of IIdentity (with some added properties).
I have this at the moment:
var user = new Mock<IPrincipal>();
var identity = new Mock<CustomIdentity>();
user.Setup(ctx => ctx.Identity).Returns(identity.Object);
identity.SetupGet(id => id.IsAuthenticated).Returns(true);
identity.SetupGet(id => id.LoginName).Returns("test");
// IsAuthenticated is the implementation of the IIdentity interface and LoginName
However when I run this test in VS2008 then I get the following error message:
Invalid setup on a non-overridable member: id => id.IsAuthenticated
Why is this happening? And most important, what do I need to do to solve it?
Grz, Kris.
You should mock IIdentity (instead of CustomIdentity - only possible if the variables you are mocking are declared in the interface) or declare the used variables as virtual.
To mark as virtual, do this: In your concrete class CustomIdentity, use
public virtual bool isAuthenticated { get; set; }
instead of
public bool isAuthenticated { get; set; }
Moq and other free mocking frameworks doesn't let you mock members and methods of concrete class types, unless they are marked virtual.
Finally, you could create the mock yourself manually. You could inherit CustomIdentity to a test class, which would return the values as you wanted. Something like:
internal class CustomIdentityTestClass : CustomIdentity
{
public new bool isAuthenticated
{
get
{
return true;
}
}
public new string LoginName
{
get
{
return "test";
}
}
}
This class would be only used in testing, as a mock for your CustomIdentity.
--EDIT
Answer to question in comments.
Are you mocking against the interface IIdentity, or mocking against your custom type?
Without having a fuller code snippet to look at, I am guessing that it is complaining that the IsAuthenticated is not marked as virtual in your custom implementation. However, this could only be the case if you were mocking against the concrete type, not the interface.