About decorating custom data on individual and every web flow

36 views
Skip to first unread message

Y G

unread,
Jul 24, 2024, 7:30:18 AM (yesterday) Jul 24
to CAS Community
Hi everyone,

My questions are:

1. For an individual flow based java decoration solution, how can i add flowVariable definition on the password reset flow correctly?
2. Is there a global way of defining custom datas for thmeleaf html using java other than custom groovy script or rest call result?

Any help would be much appreciated.

Details about my problem:

For a custom CAS theming, i wanted to decorate every page with this custom data class:

package tr.com.mycompany.cas.webflow;

import java.io.Serializable;
import java.util.List;
import java.util.Random;
import tr.com.
mycompany.cas.utils.AppInfo;

public class WebFlowCustomData implements Serializable {

  public String getRegistrationUrl() {
    String env = AppInfo.getEnvName();
    return String.format(
        "https://kayit%s.mycompany.com.tr/reg-form",
        "prod".equalsIgnoreCase(env) ? "" : "-" + env
    );
  }

  public String getRandomVideoSrc() {
    List<String> vids = List.of(
        "/cas/themes/theme2024/img/introDemo.webm",
        "/cas/themes/theme2024/img/loop.webm",
        "/cas/themes/theme2024/img/intro-light1.webm"
    );
    return vids.get(new Random().nextInt(3));
  }

}


Upon reading about Extending CAS Webflow(https://apereo.github.io/cas/6.6.x/webflow/Webflow-Customization-Extensions.html)  page , i tried doing it like this:
First add the customData variables in login and logout flows in this class.

package tr.com.mycompany.cas.webflow;

import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.configurer.AbstractCasWebflowConfigurer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;

public class CustomWebFlowDecorator extends AbstractCasWebflowConfigurer {
  public CustomWebFlowDecorator(FlowBuilderServices flowBuilderServices,
                                FlowDefinitionRegistry flowDefinitionRegistry,
                                ConfigurableApplicationContext applicationContext,
                                CasConfigurationProperties casProperties) {
    super(flowBuilderServices, flowDefinitionRegistry, applicationContext, casProperties);
  }

  @Override
  protected void doInitialize() {
    super.createFlowVariable(super.getLoginFlow(), "customData", WebFlowCustomData.class);
    super.createFlowVariable(super.getLogoutFlow(), "customData", WebFlowCustomData.class);
  }
}



And then, to register this class to the configuration i added the class below to the overlay project.


package tr.com.mycompany.cas.webflow;

import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConfigurer;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.flow.CasWebflowExecutionPlan;
import org.apereo.cas.web.flow.CasWebflowExecutionPlanConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;


@AutoConfiguration
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class WebFlowConfig implements CasWebflowExecutionPlanConfigurer {

  @Autowired
  private CasConfigurationProperties casProperties;

  /**
   * flow definition registry for login.
   */
  @Autowired
  @Qualifier(CasWebflowConstants.BEAN_NAME_LOGIN_FLOW_DEFINITION_REGISTRY)
  private FlowDefinitionRegistry loginFlowDefinitionRegistry;

  /**
   * flow definition registry for logout.
   */
  @Autowired
  @Qualifier(CasWebflowConstants.BEAN_NAME_LOGOUT_FLOW_DEFINITION_REGISTRY)
  private FlowDefinitionRegistry logoutFlowDefinitionRegistry;

  @Autowired
  private ConfigurableApplicationContext applicationContext;

  @Autowired
  private FlowBuilderServices flowBuilderServices;

  @ConditionalOnMissingBean(name = "loginFlowCustomDecoratorConfigurer")
  @Bean
  public CasWebflowConfigurer loginFlowCustomDecoratorConfigurer() {
    CustomWebFlowDecorator customWebFlowDecorator = new CustomWebFlowDecorator(flowBuilderServices,
        loginFlowDefinitionRegistry, applicationContext, casProperties);
    customWebFlowDecorator.setLogoutFlowDefinitionRegistry(logoutFlowDefinitionRegistry);
    return customWebFlowDecorator;
  }

  @Override
  public void configureWebflowExecutionPlan(final CasWebflowExecutionPlan plan) {
    plan.registerWebflowConfigurer(loginFlowCustomDecoratorConfigurer());
  }
}


and lastly i added this class to spring factories file.

Cas documentation describes only login flow, for adding the same data on logout flow, i checked, autowired the logoutFlowDefinitionRegistry first, and used it on the setLogoutFlowDefinitionRegistry setter method of my CustomWebFlowDecorator. After that CustomWebFlowDecorator's doInitialize flowVariables worked without any problem.

I wanted to add this flow variable inside password reset flow too, and trying to add it like this did not work(null value on thymeleaf htmls and a warning on startup about not setup correctly):

...
  protected void doInitialize() {
  ...
  super.createFlowVariable(super.getFlow("pswdreset"), "customData", WebFlowCustomData.class);
...


Have a wonderful day.
Yusuf Gunduz.

Ray Bon

unread,
Jul 24, 2024, 7:30:01 PM (17 hours ago) Jul 24
to cas-...@apereo.org
Yusuf,

Could you implement the logic in javascript and add it to the pages?

Ray

From: cas-...@apereo.org <cas-...@apereo.org> on behalf of Y G <yusuf....@gmail.com>
Sent: 24 July 2024 04:24
To: CAS Community <cas-...@apereo.org>
Subject: [cas-user] About decorating custom data on individual and every web flow
 
You don't often get email from yusuf....@gmail.com. Learn why this is important
--
- Website: https://apereo.github.io/cas
- List Guidelines: https://goo.gl/1VRrw7
- Contributions: https://goo.gl/mh7qDG
---
You received this message because you are subscribed to the Google Groups "CAS Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cas-user+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/afbb62e7-c4ce-4e86-a27b-3eedbfe2aa2en%40apereo.org.

Y G

unread,
6:38 AM (6 hours ago) 6:38 AM
to CAS Community, Ray Bon
That could be a solution for most use-cases (and i could even move the WebFlowCustomData.getRandomVideoSrc() method to js) but, i would like to test and implement for a java backed/backend flow extending solution the way i've written. The difficulty that i think is, when a need of decoration(loading of external/additional data to CAS web views to be used) that effects the view(thymeleaf htmls) occurs, a need of groovy knowledge or coding or implementing seperate project/service/endpoint happens.

To express my example context further, i wrote the  WebFlowCustomData.getRegistrationUrl()method that returns a url that can be changed according to deployed cas environment. In addition to production profile, i have set up dev,qa,prp profiles in my CAS 6.6.x overlay app. I would like this method to give me the necessary url, according to active CAS profile.

I will write an example CAS Overlay project, send to a github repo, and announce it here soon for your convenience and testing.

Thank you and  a have nice day.
Yusuf Gündüz

25 Temmuz 2024 Perşembe tarihinde saat 02:30:01 UTC+3 itibarıyla Ray Bon şunları yazdı:
Reply all
Reply to author
Forward
0 new messages