test 2
WF Brandcentral
|Hello World Component
|Text property:
|lalala :)|
Model message:
|Hello World! | Resource type is: brandcentral/components/helloworld | Current page is: /content/brandcentral/us/en ||
Open dhulipudi opened 3 months ago
2 floating text
import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.lang.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.RequestAttribute; import org.apache.sling.models.annotations.injectorspecific.SlingObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageManager; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable;
/**
*/
@Model(adaptables = { SlingHttpServletRequest.class, Resource.class}) public class NavigationModel { private final Logger LOG = LoggerFactory.getLogger(NavigationModel.class);
protected static final String RESOURCE_TYPE = "wellsfargobc/components/navigation";
private List<NavigationItem> items;
@SlingObject
private Resource currentResource;
@SlingObject
private ResourceResolver resourceResolver;
private String currentPagePath;
@RequestAttribute
@org.apache.sling.models.annotations.Optional
private String path;
@PostConstruct
protected void init() {
LOG.debug("NavigationModel:Path:{}", path);
if ( path != null ) {
String[] rootPathArray = path.split("/");
List<String> pathList = Arrays.asList(rootPathArray).subList(0, 7);
if ( path.contains("brand-standards")) {
pathList = Arrays.asList(rootPathArray).subList(0, 8);
}
String rootPath = StringUtils.join(pathList,"/");
LOG.debug("rootPath:{}", rootPath);
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(rootPath);
if (currentPage != null) {
LOG.debug("NavigationModel:currentPage:{} Name:{}", currentPage, currentPage.getName());
items = buildNavigation(currentPage);
if ( !currentPage.getName().equalsIgnoreCase("brand-standards"))
items.add(0, new NavigationItem(currentPage, false));
LOG.debug("Items:{} Size: {}", items, items.size());
}
}
}
@Nullable
public List<NavigationItem> getItems() {
return items;
}
/**
* Build the Navigation for the current resource
* @param currentPage
* @return
*/
private List<NavigationItem> buildNavigation(@NotNull final Page currentPage) {
List<NavigationItem> navigationItems = new ArrayList<>();
Iterator<Page> siblings = currentPage.listChildren();
while (siblings.hasNext()) {
Page sibling = siblings.next();
if (!sibling.isHideInNav()) {
navigationItems.add(new NavigationItem(sibling));
}
}
return navigationItems;
}
public class NavigationItem {
private String title;
private String url;
private boolean isActive;
private List<NavigationItem> children;
public NavigationItem(@NotNull final Page page, @NotNull final boolean includeChild) {
this.title = page.getTitle();
this.url = page.getPath() + ".html";
this.isActive = page.getPath().equalsIgnoreCase(currentPagePath);
if (includeChild && page.listChildren().hasNext()) {
this.children = buildNavigation(page);
}
}
public NavigationItem(@NotNull final Page page) {
this.title = page.getTitle();
this.url = page.getPath() + ".html";
this.isActive = page.getPath().equalsIgnoreCase(currentPagePath);
if (page.listChildren().hasNext()) {
this.children = buildNavigation(page);
}
}
public boolean isActive() {
return isActive;
}
public List<NavigationItem> getChildren() {
return children;
}
public String getUrl() {
return url;
}
public String getTitle() {
return title;
}
}
}
${item.title}
import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.apache.sling.models.annotations.injectorspecific.RequestAttribute; import org.apache.sling.models.annotations.injectorspecific.SlingObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageManager;
/**
Build the Navigational items for the current page */ @Model(adaptables = { SlingHttpServletRequest.class, Resource.class }) public class NavigationModel { private final Logger LOG = LoggerFactory.getLogger(NavigationModel.class);
private List
@SlingObject private Resource currentResource;
@SlingObject private ResourceResolver resourceResolver;
private String currentPagePath;
@RequestAttribute @Optional private String path;
@PostConstruct
protected void init() {
LOG.debug("NavigationModel:Path:{}", path);
if (path != null) {
String[] rootPathArray = path.split("/");
List
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(rootPath);
if (currentPage != null) {
LOG.debug("NavigationModel:currentPage:{} Name:{}", currentPage, currentPage.getName());
items = buildNavigation(currentPage);
if (!currentPage.getName().equalsIgnoreCase("brand-standards"))
items.add(0, new NavigationItem(currentPage, false));
LOG.debug("Items:{} Size: {}", items, items.size());
}
}
}
public List
private List
Iterator<Page> siblings = currentPage.listChildren();
while (siblings.hasNext()) {
Page sibling = siblings.next();
if (!sibling.isHideInNav()) {
navigationItems.add(new NavigationItem(sibling));
}
}
return navigationItems;
}
public class NavigationItem {
private String title;
private String url;
private boolean isActive;
private List
public NavigationItem(final Page page, final boolean includeChild) {
this.title = page.getTitle();
this.url = page.getPath() + ".html";
this.isActive = page.getPath().equalsIgnoreCase(currentPagePath);
if (includeChild && page.listChildren().hasNext()) {
this.children = buildNavigation(page);
}
}
public NavigationItem(final Page page) {
this(page, page.listChildren().hasNext());
}
public boolean isActive() {
return isActive;
}
public List<NavigationItem> getChildren() {
return children;
}
public String getUrl() {
return url;
}
public String getTitle() {
return title;
}
} }
============= 333===
import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.apache.sling.models.annotations.injectorspecific.RequestAttribute; import org.apache.sling.models.annotations.injectorspecific.SlingObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageManager;
/**
Build the Navigational items for the current page */ @Model(adaptables = { SlingHttpServletRequest.class, Resource.class }) public class NavigationModel { private final Logger LOG = LoggerFactory.getLogger(NavigationModel.class);
private List
@SlingObject private Resource currentResource;
@SlingObject private ResourceResolver resourceResolver;
private String currentPagePath;
@RequestAttribute @Optional private String path;
@PostConstruct
protected void init() {
LOG.debug("NavigationModel:Path:{}", path);
if (path != null) {
String[] rootPathArray = path.split("/");
List
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
Page currentPage = pageManager.getContainingPage(rootPath);
if (currentPage != null) {
LOG.debug("NavigationModel:currentPage:{} Name:{}", currentPage, currentPage.getName());
items = buildNavigation(currentPage);
if (!currentPage.getName().equalsIgnoreCase("brand-standards"))
items.add(0, new NavigationItem(currentPage, false));
LOG.debug("Items:{} Size: {}", items, items.size());
}
}
}
public List
private List
Iterator<Page> siblings = currentPage.listChildren();
while (siblings.hasNext()) {
Page sibling = siblings.next();
if (!sibling.isHideInNav()) {
navigationItems.add(new NavigationItem(sibling));
}
}
return navigationItems;
}
public class NavigationItem {
private String title;
private String url;
private boolean isActive;
private List
public NavigationItem(final Page page, final boolean includeChild) {
this.title = page.getTitle();
this.url = page.getPath() + ".html";
this.isActive = page.getPath().equalsIgnoreCase(currentPagePath);
if (includeChild && page.listChildren().hasNext()) {
this.children = buildNavigation(page);
}
}
public NavigationItem(final Page page) {
this(page, page.listChildren().hasNext());
}
public boolean isActive() {
return isActive;
}
public List<NavigationItem> getChildren() {
return children;
}
public String getUrl() {
return url;
}
public String getTitle() {
return title;
}
} }
===================== import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*;
import com.day.cq.wcm.api.Page; import com.bsc.ewp.slingmodels.NavigationModel; import com.bsc.ewp.slingmodels.NavigationModel.NavigationItem; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.SlingHttpServletRequest; import org.junit.Before; import org.junit.Test;
import java.util.Iterator;
public class NavigationModelTest { private NavigationModel navigationModel; private Page mockPage; private ResourceResolver mockResolver; private SlingHttpServletRequest mockRequest; private Resource mockResource;
@Before
public void setUp() {
// Create mock objects
mockPage = mock(Page.class);
mockResolver = mock(ResourceResolver.class);
mockRequest = mock(SlingHttpServletRequest.class);
mockResource = mock(Resource.class);
// Set up mock behavior
when(mockPage.getTitle()).thenReturn("Test Title");
when(mockPage.getPath()).thenReturn("/content/test");
when(mockPage.listChildren()).thenReturn(mock(Iterator.class));
when(mockResolver.adaptTo(Page.class)).thenReturn(mockPage);
when(mockResource.adaptTo(Page.class)).thenReturn(mockPage);
when(mockRequest.getResource()).thenReturn(mockResource);
// Create NavigationModel object
navigationModel = new NavigationModel();
navigationModel.resourceResolver = mockResolver;
navigationModel.currentResource = mockResource;
navigationModel.init();
}
@Test
public void testGetItems() {
assertEquals(1, navigationModel.getItems().size());
}
@Test
public void testNavigationItemGetUrl() {
NavigationItem item = navigationModel.getItems().get(0);
assertEquals("/content/test.html", item.getUrl());
}
@Test
public void testNavigationItemGetTitle() {
NavigationItem item = navigationModel.getItems().get(0);
assertEquals("Test Title", item.getTitle());
}
}
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*;
import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageManager; import com.bsc.ewp.slingmodels.NavigationModel; import com.bsc.ewp.slingmodels.NavigationModel.NavigationItem; import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(AemContextExtension.class) public class NavigationModelTest { private final AemContext context = new AemContext();
@BeforeEach
public void setUp() {
// Create a Page object
Page page = context.create().page("/content/test", "test-template", "Test Title");
// Set up the request
MockSlingHttpServletRequest request = context.request();
request.setResource(page.adaptTo(Resource.class));
// Set up the PageManager
PageManager pageManager = context.pageManager();
when(pageManager.getContainingPage(anyString())).thenReturn(page);
// Set up the NavigationModel
NavigationModel navigationModel = request.adaptTo(NavigationModel.class);
navigationModel.resourceResolver = context.resourceResolver();
navigationModel.currentResource = request.getResource();
navigationModel.path = "/content/test";
navigationModel.init();
}
@Test
public void testGetItems() {
NavigationModel navigationModel = context.request().adaptTo(NavigationModel.class);
assertEquals(1, navigationModel.getItems().size());
}
@Test
public void testNavigationItemGetUrl() {
NavigationModel navigationModel = context.request().adaptTo(NavigationModel.class);
NavigationItem item = navigationModel.getItems().get(0);
assertEquals("/content/test.html", item.getUrl());
}
@Test
public void testNavigationItemGetTitle() {
NavigationModel navigationModel = context.request().adaptTo(NavigationModel.class);
NavigationItem item = navigationModel.getItems().get(0);
assertEquals("Test Title", item.getTitle());
}
}
<truncateText
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/radiogroup"
fieldLabel="trunc_text"
name="./truncateText"
required="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<no_trunc
jcr:primaryType="nt:unstructured"
text="no_trunc"
value="no-truncate"/>
<lines3
jcr:primaryType="nt:unstructured"
checked="{Boolean}true"
text="three_lines"
value="truncate-lines-to-3"/>
<lines4
jcr:primaryType="nt:unstructured"
text="four_lines"
value="truncate-lines-to-4"/>
</items>
</truncateText>
@Model(adaptables = {Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class TextCTAModelLinkItem {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Self
@Via("resource")
private Resource resource;
@ValueMapValue
@Optional
private String path;
@ValueMapValue
@Optional
private String text;
@ValueMapValue
@Optional
private Boolean openInNewWindow;
public String getPath() {
return path;
}
public String getText() {
return text;
}
public String getTarget(){
return openInNewWindow ? "_blank" : null;
}
@PostConstruct
private void activate(){
// we will treat this as a link to a page - path, with no extension
if(path != null && path.startsWith("/content") && !path.startsWith("/content/dam") && !path.contains(".html")){
path = path + ".html";
}
}
}
=========
dialog
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured" jcr:title="What's New Header" sling:resourceType="cq/gui/components/authoring/dialog"> <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container">
</content>
</jcr:root>
====
import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Default; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.apache.sling.models.annotations.injectorspecific.ChildResource; import org.apache.sling.models.annotations.injectorspecific.Self; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct; import java.lang.invoke.MethodHandles; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport;
/**
see /apps/joule/components/content/textcta/textcta.html */ @Model(adaptables = {Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class TextCTAModel {
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Self private Resource resource;
@ValueMapValue @Optional private String headingText;
@ValueMapValue @Optional private String bodyText;
@ValueMapValue @Optional @Default(values = "grey-bg") private String backgroundColor; // grey-bg or ""
@ValueMapValue @Optional @Default(values = "header3") // header3 or header2 private String headingTextStyle;
@ValueMapValue @Optional @Default(values = "body1") // body1 or header5 private String bodyTextStyle;
@ValueMapValue @Optional @Default(values = "primary-cta") // right now 'primary-cta' is the only option private String buttonStyle;
@ChildResource(name = "links") private Resource linksResource;
private List
public String getBodyText() { return bodyText; }
public String getHeadingText() { return headingText; }
public String getBodyTextStyle() { return bodyTextStyle; }
public String getHeadingTextStyle() { return headingTextStyle; }
public String getBackgroundColor() { return backgroundColor; }
public String getButtonStyle() { return buttonStyle; }
public List
@PostConstruct private void activate(){ /**
}
}
.cmp-page-header--breadcrumbs-title { // NOTE: This applies to an alternative page header style in EWP Left Navigation Template - Breadcrumb Container Policy
h1 { margin: space(md) 0.625rem space(3x); // NOTE: The l/r is a one-off size to align the h1 with the full-width primary nav } }
// Background Colors
.cmp-container { &:first-child { background: transparent; } }
.cmp-container--accent {
.cmp-container { &:first-child { background: $accent-primary-20; } } }
.cmp-container--action {
.cmp-container { &:first-child { background: $action-primary-97; } } }
.cmp-container--assertive {
.cmp-container { &:first-child { background: $neutral-00; } } }
.cmp-container--ghost {
.cmp-container { &:first-child { background: $neutral-100; } } }
.cmp-container--gradient-assertive {
.cmp-container { &:first-child { background: $gradient-assertive; } } }
.cmp-container--gradient-subtle {
.cmp-container { &:first-child { background: $gradient-subtle; } } }
.cmp-container--subtle {
.cmp-container { &:first-child { background: $neutral-95; } } }
// Background Patterns
.cmp-container--pattern-arrow {
.cmp-container { &:first-child { position: relative;
&::after {
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
background-image: url('/etc.clientlibs/ewp/clientlibs/clientlib-default/resources/images/pattern-arrow.svg');
background-position-x: left;
background-position-y: top;
background-repeat: repeat-y;
background-size: cover;
content: '';
}
> * {
position: relative;
z-index: 2;
}
}
}
&.cmp-container--accent {
.cmp-container { &:first-child { &::after { background-image: url('/etc.clientlibs/ewp/clientlibs/clientlib-default/resources/images/pattern-arrow-accent.svg'); } } } }
&.cmp-container--action {
.cmp-container { &:first-child { &::after { background-image: url('/etc.clientlibs/ewp/clientlibs/clientlib-default/resources/images/pattern-arrow-action.svg'); } } } }
&.cmp-container--assertive {
.cmp-container { &:first-child { &::after { background-image: url('/etc.clientlibs/ewp/clientlibs/clientlib-default/resources/images/pattern-arrow-assertive.svg'); } } } }
&.cmp-container--gradient-assertive {
.cmp-container { &:first-child { &::after { background-image: url('/etc.clientlibs/ewp/clientlibs/clientlib-default/resources/images/pattern-arrow-assertive-gradient.svg'); } } } } }
// Decorative Treatments
.cmp-container--border-accent {
.cmp-container { &:first-child { @include border-gradient-accent; } }
&.cmp-container--assertive, &.cmp-container--gradient-assertive {
.cmp-container { &:first-child { border: space(sm) solid $accent-secondary-60; } } }
&.cmp-container--accent {
.cmp-container { &:first-child { border: space(sm) solid $accent-primary-60; } } } }
.cmp-container--shadow {
.cmp-container { &:first-child { box-shadow: $box-shadow-tertiary; } } }
.cmp-container--split {
.cmp-container { &:first-child { position: relative; background: transparent;
&::before {
// NOTE: this is the background color
position: absolute;
top: 0;
right: 0;
bottom: 25%;
left: 0;
z-index: -1;
content: '';
}
&::after {
// NOTE: this is the arrow pattern
height: 75%;
}
}
}
&.cmp-container--accent {
.cmp-container { &:first-child { &::before { background: $accent-primary-20; } } } }
&.cmp-container--action {
.cmp-container { &:first-child { &::before { background: $action-primary-97; } } } }
&.cmp-container--assertive {
.cmp-container { &:first-child { &::before { background: $neutral-00; } } } }
&.cmp-container--ghost {
.cmp-container { &:first-child { &::before { background: $neutral-100; } } } }
&.cmp-container--gradient-assertive {
.cmp-container { &:first-child { &::before { background: $gradient-assertive; } } } }
&.cmp-container--gradient-subtle {
.cmp-container { &:first-child { &::before { background: $gradient-subtle; } } } }
&.cmp-container--subtle {
.cmp-container { &:first-child { &::before { background: $neutral-95; } } } }
@media (min-width: 992px) {
.cmp-container { &:first-child { &::before { // NOTE: this is the background color bottom: 50%; }
&::after {
// NOTE: this is the arrow pattern
height: 50%;
}
}
}
} }
// Padding // NOTE: The naming convention is slightly different here since the default is truly 0/remove // We set default to 6x since that would be the default inset padding, in the event that the author adds padding
.cmp-container--padding-increase {
.cmp-container { &:first-child { padding: space(8x); } } }
.cmp-container--padding-default {
.cmp-container { &:first-child { padding: space(6x); } } }
.cmp-container--padding-decrease {
.cmp-container { &:first-child { padding: space(4x); } } }
// Margin Top
.cmp-container--margin-top-increase-2 {
.cmp-container { &:first-child { margin-top: space(12x); } } }
.cmp-container--margin-top-increase-1 {
.cmp-container { &:first-child { margin-top: space(8x); } } }
.cmp-container--margin-top-default {
.cmp-container { &:first-child { margin-top: space(6x); } } }
.cmp-container--margin-top-decrease-1 {
.cmp-container { &:first-child { margin-top: space(4x); } } }
.cmp-container--margin-top-decrease-2 {
.cmp-container { &:first-child { margin-top: space(3x); } } }
/ ----Teaser Component JS---- / var comp = window.comp || {}; comp.teaser = {}; comp.teaser = { insertTargetDiv: function () { $('.cmp-teaser--brand-element .cmp-teaser__content').prepend( '
' ); },initArrowsTracking: function () { window.dataLayer = window.dataLayer || []; var $targetDiv = $('#iconAdvancingArrows');
$targetDiv.on('click', function () {
window.dataLayer.push({
event: 'teaserArrowsClicked'
});
});
} };
comp.teaser.insertTargetDiv(); comp.teaser.initArrowsTracking();
.cmp-teaser--hero { &.cmp-teaser--brand-element { &:not(.cmp-teaser--interactive) { .cmp-teaser__content { position: relative; border-bottom: space(sm) solid transparent; padding-top: calc(space(4x) + space(3x)); // NOTE: This is the regular padding + half the height of the arrows
&::before {
position: absolute;
top: - space(3x);
left: space(4x);
z-index: 2;
display: block;
width: space(8x);
height: space(6x);
background: url('/etc.clientlibs/ewp/clientlibs/clientlib-default/resources/images/bsc-advancing-arrows.svg');
background-size: 100%;
content: '';
}
.icon-advancing-arrows {
position: absolute;
top: - space(3x);
left: space(4x);
z-index: 3;
display: block;
width: space(8x);
height: space(6x);
}
&::after {
bottom: - space(sm);
@include decorative-bar;
@include animated-gradient-brand;
z-index: 1;
content: '';
}
@media (min-width: 768px) {
margin-top: calc(space(6x) + space(3x)); // NOTE: This is the regular margin + half the height of the arrows
}
&:first-child {
padding-top: space(4x);
&::before {
position: relative;
top: 0;
left: 0;
margin-bottom: space(4x);
}
.icon-advancing-arrows {
top: space(4x);
}
&::after {
bottom: - space(sm);
@include animated-gradient-brand;
}
@media (min-width: 768px) {
margin-top: unset;
}
}
}
&.cmp-teaser--hero-center {
.cmp-teaser__content {
&::before,
.icon-advancing-arrows {
left: calc(50% - space(4x));
}
}
}
&.cmp-teaser--hero-overlap {
.cmp-teaser__content {
margin: - space(8x) space(6x) 0;
}
@media (min-width: 992px) {
.cmp-teaser__content {
margin: 0;
}
}
}
}
} }
Text property:
|lalala :)|
Model message:
|Hello World! | Resource type is: brandcentral/components/helloworld | Current page is: /content/brandcentral/us/en ||
|
<!DOCTYPE HTML>
Text property:
lalala :)
Model message:
Hello World! Resource type is: brandcentral/components/helloworld Current page is: /content/brandcentral/us/en
test 2
display: flex; flex-wrap: wrap; }
flex: 1 0 50%; / This makes the items take up 50% of the container's width, allowing two items per row / }
@media (max-width: 768px) { / Adjust this value as needed /
flex-direction: column;
} }
package com.wellsfargo.bc.core.services.auth;
import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.stream.Stream;
import javax.jcr.LoginException; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials; import org.apache.sling.auth.core.spi.AuthenticationFeedbackHandler; import org.apache.sling.auth.core.spi.AuthenticationHandler; import org.apache.sling.auth.core.spi.AuthenticationInfo; import org.apache.sling.auth.core.spi.DefaultAuthenticationFeedbackHandler; import org.apache.sling.jcr.api.SlingRepository; import org.apache.sling.auth.core.AuthUtil; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.osgi.service.metatype.annotations.AttributeDefinition; import org.osgi.service.metatype.annotations.Designate; import org.osgi.service.metatype.annotations.ObjectClassDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
import com.day.crx.security.token.TokenCookie;
import static org.apache.sling.auth.core.spi.AuthenticationHandler.TYPE_PROPERTY; import static org.apache.sling.auth.core.spi.AuthenticationHandler.PATH_PROPERTY; import static org.osgi.framework.Constants.SERVICE_DESCRIPTION; import static org.osgi.framework.Constants.SERVICE_RANKING; import static org.osgi.service.component.annotations.ReferenceCardinality.MULTIPLE; import static org.osgi.service.component.annotations.ReferencePolicy.DYNAMIC; import static org.apache.commons.lang3.StringUtils.EMPTY;
/**
*/ @Designate(ocd = WFAuthenticationHandler.Config.class)
@Component(service = { AuthenticationHandler.class, AuthenticationFeedbackHandler.class }, // configurationPolicy = REQUIRE, property = { PATH_PROPERTY + "=/content", TYPE_PROPERTY + "= WF_OAUTH", SERVICE_DESCRIPTION + "= WellsFargo Federated Authenticator", SERVICE_RANKING + ":Integer=80000" }) public class WFAuthenticationHandler extends DefaultAuthenticationFeedbackHandler implements AuthenticationHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(WFAuthenticationHandler.class);
@ObjectClassDefinition(name = "CWA AuthenticationHandler Configuration", description = "Configuration for CWA AuthenticationHandler.")
public @interface Config {
@AttributeDefinition(name = "WF AuthenticationHandler Paths")
String[] path() default { "/content/brandcentral" };
@AttributeDefinition(name = "Auth Request Url")
String cwaAuthRequestUrl() default "";
@AttributeDefinition(name = "Callback Url")
String cwaCallbackUrl() default "";
@AttributeDefinition(name = "SessionManager Callback Url")
String sessionManagerCallbackUrl() default "";
@AttributeDefinition(name = "SessionManager Logout Url")
String sessionManagerLogoutUrl() default "";
@AttributeDefinition(name = "SessionManager UserInfo Url")
String sessionManagerUserInfoUrl() default "";
}
private Config config;
private final String REQUEST_METHOD = "GET";
private final String USER_NAME = "j_username";
private final String PASSWORD = "j_password";
private static final String TOKEN_ID = ".token";
private final ConcurrentMap<String, WFLoginCallback> callbacks = new ConcurrentHashMap<>();
@Reference
private SlingRepository repository;
@Override
public AuthenticationInfo extractCredentials(HttpServletRequest request, HttpServletResponse response) {
LOGGER.info("extractCredentials");
AuthenticationInfo authenticationInfo = null;
String j_username = request.getParameter(USER_NAME);
String j_password = request.getParameter(PASSWORD);
if ((request.getRequestURI().contains("j_security_check"))) {
try {
authenticationInfo = basicAuth(request, response, j_username, j_password);
} catch (LoginException ex) {
LOGGER.error(ex.getMessage());
return null;
}
}
return authenticationInfo;
}
private AuthenticationInfo basicAuth(HttpServletRequest request, HttpServletResponse response,
String userName, String password) throws LoginException {
AuthenticationInfo authInfo = null;
if ((userName != null && password != null)) {
authInfo = new AuthenticationInfo("TOKEN", userName);
SimpleCredentials creds = new SimpleCredentials(userName,
password.toCharArray());
Session session = null;
try {
session = this.repository.login(creds);
this.repository.login(creds);
if (session != null) {
// create a new AuthenticationInfo object that makes use of the standard
// AEM token authentication
authInfo = new AuthenticationInfo("TOKEN",
userName);
// and we set a dummy token which will be updated
creds.setAttribute(TOKEN_ID, "");
// log in using the credentials to record the log in event
repository.login(creds);
// use the associated session to create TokenCredentials
TokenCredentials tc = new TokenCredentials((String) creds.getAttribute(TOKEN_ID));
// and set the token-credentials in authenticationInfo object
authInfo.put("user.jcr.credentials", tc);
// set or update login token cookie
String repoId = repository.getDescriptor("crx.cluster.id");
TokenCookie.update(request, response, repoId, tc.getToken(),
repository.getDefaultWorkspace(), true);
if (session.isLive()) {
session.logout();
}
LOGGER.info("authInfo:{}", authInfo);
return authInfo;
}
} catch (LoginException e) {
LOGGER.error(
this.getClass().getName() + " extractCredentials(..) Failed to log user in" + e.getMessage(),
e);
e.printStackTrace();
} catch (RepositoryException e) {
LOGGER.error(
this.getClass().getName() + " extractCredentials(..) Failed to log user in" + e.getMessage(),
e);
e.printStackTrace();
}
}
return authInfo;
}
@Override
public boolean requestCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException {
return false;
}
@Override
public void dropCredentials(HttpServletRequest request, HttpServletResponse response) throws IOException {
String appId = request.getParameter("appId");
LOGGER.info("dropCredentials for appId: [{}]", appId);
if (StringUtils.isNotEmpty(appId)) {
if (Boolean.parseBoolean(request.getParameter("sm"))) {
LOGGER.info("Sending AppId: [{}] to SessionManager for logout.", appId);
this.redirect(response, this.config.sessionManagerLogoutUrl() + "?appId=" + appId, true);
} else {
this.redirect(response, "/bin/public/servlets/cwa/logout?appId=" + appId, true);
}
}
}
// <<----------------------------------- AuthenticationFeedbackHandler
// ----------------------------------->>
@Override
public void authenticationFailed(HttpServletRequest request, HttpServletResponse response,
AuthenticationInfo authInfo) {
LOGGER.info("authenticationFailed");
this.callbacks.forEach((name, callback) -> {
try {
if (callback.canHandle(request)) {
callback.onLoginFailure(request);
}
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
});
}
@Override
public boolean authenticationSucceeded(HttpServletRequest request, HttpServletResponse response,
AuthenticationInfo authInfo) {
LOGGER.info("authenticationSucceeded");
this.callbacks.forEach((name, callback) -> {
try {
LOGGER.info("Name:{}", name);
if (callback.canHandle(request)) {
callback.onLoginSuccess(request);
}
} catch (Exception ex) { // NOSONAR
LOGGER.error(ex.getMessage(), ex);
}
});
// return true so that SlingAuthenticator stops further request processing and
// redirect to the given url instead.
return redirectQuietly(response, AuthUtil.getLoginResource(request, EMPTY), false);
}
@Reference(service = WFLoginCallback.class, cardinality = MULTIPLE, policy = DYNAMIC)
protected void bindCWALoginCallback(WFLoginCallback callback) {
this.callbacks.put(callback.getTenantName(), callback);
LOGGER.info("Added [{}] WFLoginCallback!", callback.getTenantName());
}
protected void unbindCWALoginCallback(WFLoginCallback callback) {
if (this.callbacks.remove(callback.getTenantName()) != null) {
LOGGER.info("Removed [{}] WFLoginCallback!", callback.getTenantName());
}
}
private boolean redirectQuietly(HttpServletResponse resp, String url, boolean encodeUrl) {
boolean outcome = false;
try {
if (resp.isCommitted()) {
LOGGER.error("Response already committed!!");
} else {
LOGGER.debug("Redirecting to url: [{}]", url);
resp.sendRedirect(encodeUrl ? resp.encodeRedirectURL(url) : url);
outcome = true;
}
} catch (IOException ex) {
LOGGER.error(ex.getMessage(), ex);// NOSONAR
}
return outcome;
}
private void redirect(HttpServletResponse resp, String url, boolean encodeUrl) throws IOException {
LOGGER.debug("Redirecting to: [{}]", url);
resp.sendRedirect(encodeUrl ? resp.encodeRedirectURL(url) : url);
}
@Activate
protected void start(Config config) {
this.config = config;
Stream.of(config.path())
.forEach(path -> LOGGER.info("WFAuthenticationHandler listening at path: [{}]", path));
}
}