Configuring Keycloak provider with SPI - jboss

I am trying to configure one of my providers factory (its ID is "phone-verification") with the following code :
#Override
public void init(Config.Scope config) {
String lifespan = config.get("lifespan");
logger.warn("Lifespan : " + lifespan);
}
And I have my configuration done in standalone.xml with the following property :
<spi name="phoneVerification">
<default-provider>phone-verification</default-provider>
<provider name="phone-verification" enabled="true">
<properties>
<property name="lifespan" value="2592000"/>
</properties>
</provider>
</spi
However config.get("lifespan") always returns null. Is there any extra step or am I doing anything wrong ?
NOTE : I specified the config file with the /keycloak/bin/standalone.sh --server-config=standalone.xml.

Hi I had the same problem and I solved it by replacing the name attribute of spi tag by the name of an SPI type. There is so many SPI types inside Keycloak.
For exemple if your provide is implementing Authenticator SPI you should configure your provider like this:
<spi name="authenticator">
<provider name="Basic-Authenticator" enabled="true">
<properties>
<property name="user" value="testUser"/>
</properties>
</provider>
</spi>
Same If you are implementing a requered action SPI:
<spi name="required-action">
<provider name="Basic-Migration" enabled="true">
<properties>
<property name="action" value="login"/>
</properties>
</provider>
</spi>
Then just use properties in your factory class like:
#Override
public void init(Scope config) {
String username = config.get("user");
LOG.info("This is the provider property: " + username);
}
Don't forget that inside provider tag, the name attribute is the Id of provider in the provider factory class.

Related

Quarkus + Camel JPA with multiple Datasources

I'm trying to use Camel to move data from one database to another. We used to use Spring to define two different JPA components as follows:
<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jpa1" class="org.apache.camel.component.jpa.JpaComponent">
<property name="entityManagerFactory" ref="entityManagerFactory1" />
<property name="transactionManager" ref="txManager" />
</bean>
<bean id="jpa2" class="org.apache.camel.component.jpa.JpaComponent">
<property name="entityManagerFactory" ref="entityManagerFactory2" />
<property name="transactionManager" ref="txManager" />
</bean>
which allows us to use each jpa component separately in the Routes class as follows:
from(jpa("jpa1","org.src.entity.DataSource1"))
-OR-
from(jpa("jpa2","org.src.entity.DataSource2"))
But now in Quarkus I'm unable to find a way to define these JPA components!
Here is my application.properties:
#postgresql 'default datasource'
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=admin
quarkus.datasource.password=admin
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5555/postgres
quarkus.datasource.jdbc.min-size=2
quarkus.datasource.jdbc.max-size=20
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.packages=org.src.target
quarkus.hibernate-orm.log.sql=true
#oracle
quarkus.datasource.oracle.db-kind=oracle
quarkus.datasource.oracle.username=admin
quarkus.datasource.oracle.password=admin
quarkus.datasource.oracle.jdbc.url=jdbc:oracle:thin:#//{{link}}
quarkus.datasource.oracle.jdbc.min-size=2
quarkus.datasource.oracle.jdbc.max-size=20
quarkus.hibernate-orm.oracle.datasource=oracle
quarkus.hibernate-orm.oracle.packages=org.src.source
quarkus.hibernate-orm.oracle.database.default-schema=AAAA
# Quarkus Narayana JTA
quarkus.transaction-manager.object-store-directory=target/narayana
quarkus.transaction-manager.enable-recovery=true
# Camel
camel.rest.context-path=/api
I tried using the oracle datasource as a jpa component but it did not work! I also tried declaring a new JPAComponent in Routes:
#ApplicationScoped
public class Routes extends EndpointRouteBuilder {
#Inject
#PersistenceUnit("oracle")
EntityManagerFactory entityManagerFactory;
#Inject
CamelContext camelContext;
#Override
public void configure() throws Exception {
JpaComponent jpaComponent = new JpaComponent();
jpaComponent.setEntityManagerFactory(entityManagerFactory);
camelContext.addComponent("jpaComponent", jpaComponent);
}
}
But got this error instead: java.lang.ClassNotFoundException: org.springframework.transaction.support.TransactionCallback
I would really appreciate any suggestions.

Alfresco with custom authentication webservice

We have a custom authentication service which accepts a parameter over a REST service and provides a json response. Based on the response we redirect the user. I wish to integrate this webservice with our new Alfresco Box.
Is there a way to do custom base authentication instead of using LDAP or inbuilt SSO plugin?
If I understood correctly...
Implement your custom remote user mapper:
package best.package.ever;
import org.alfresco.repo.security.authentication.external.DefaultRemoteUserMapper;
public class CustomRemoteUserMapper extends DefaultRemoteUserMapper {
public boolean canHandle(HttpServletRequest request) {
return true; // TODO
}
public String getTrustedUserId(HttpServletRequest request) {
// TODO: validate & authorize... e.g. based on trusted Json Web Token
return "trusted.user.id"; // TODO
}
public String getRemoteUser(HttpServletRequest request) {
if (canHandle(request)) {
return getTrustedUserId(request);
} else {
return super.getRemoteUser(request);
}
}
}
Put your library best-package-ever.jar into tomcat\webapps\alfresco\WEB-INF\lib
Declare your custom bean and inject it into RemoteUserMapper bean: tomcat\shared\classes\alfresco\extension\authentication-custom-context.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="customRemoteUserMapper" class="best.package.ever.CustomRemoteUserMapper">
<property name="personService" ref="PersonService"/>
<property name="authorityService" ref="AuthorityService" />
</bean>
<bean id="RemoteUserMapper" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
<property name="applicationContextManager">
<ref bean="Authentication" />
</property>
<property name="interfaces">
<list>
<value>org.alfresco.repo.security.authentication.external.RemoteUserMapper</value>
<value>org.alfresco.repo.management.subsystems.ActivateableBean</value>
</list>
</property>
<property name="sourceBeanName">
<value>customRemoteUserMapper</value> <!-- extending remoteUserMapper -->
</property>
</bean>
</beans>

Alfresco API to run faceted search

I'm using Alfresco community 5.x version and I'm wondering if There are REST or any other remote alfresco apis to be able to run Faceted search.
I've seen some Restful apis to administer/manage some aspects of Faceted search viz : http://docs.alfresco.com/community5.0/references/RESTful-Facet.html
However no public APIs to run a faceted search.
I did notice that alfresco share fires the following against the core alfresco service to run its faceted search; but could not find any notes/docs related to that -
http://alfresco.mycompany.com/alfresco/s/slingshot/search
?facetFields={http://www.alfresco.org/model/content/1.0}creator,
{http://www.alfresco.org/model/content/1.0}content.mimetype,
{http://www.alfresco.org/model/content/1.0}created,
{http://www.alfresco.org/model/content/1.0}content.size,
{http://www.alfresco.org/model/content/1.0}modifier,
{http://www.alfresco.org/model/content/1.0}modified
&filters=
&term=wal
&tag=
&startIndex=0
&sort=
&site=
&rootNode=alfresco://company/home
&repo=false
&query=
&pageSize=25
&maxResults=0
&noCache=1455504682131
&spellcheck=true&
We have API based integration with Alfresco in our custom internal applications and don't use Alfresco Share.
I'm not sure if I should be using the above url or not.
Any suggestions on this?
Thanks!
Alfresco Version: 5.0.d
You can use the default search webscript:
webscripts\org\alfresco\slingshot\search\search.get.js
If you look at the code:
var params =
{
siteId: args.site,
containerId: args.container,
repo: (args.repo !== null) ? (args.repo == "true") : false,
term: args.term,
tag: args.tag,
query: args.query,
rootNode: args.rootNode,
sort: args.sort,
maxResults: (args.maxResults !== null) ? parseInt(args.maxResults, 10) : DEFAULT_MAX_RESULTS,
pageSize: (args.pageSize !== null) ? parseInt(args.pageSize, 10) : DEFAULT_PAGE_SIZE,
startIndex: (args.startIndex !== null) ? parseInt(args.startIndex, 10) : 0,
facetFields: args.facetFields,
filters: args.filters,
spell: (args.spellcheck !== null) ? (args.spellcheck == "true") : false
};
So if you present the right arguments with the facets to look for, then Alfresco will return the right faceted results.
I finally figured out how to implement and integrate the faceted search into a custom UI. the same also works with share.
create model in model manager (no hyphens)
Indexing attribute:
String: list of values whole match
Date, Number: enhanced search
For each type define the layout design - w/o this you wont be able to change type in share at least.
In share/search manager create filters/facets for fields you're interested in
Add a custom *context.xml to define a bean with your custom FacetQueryProvider implementation. inject that into the facet.solrFacetHelper bean
The custom FacetQueryProvider e.g. DollarAmountDisplayHandler basically provides facet queries based on the dollar amount buckets bean in the *context.xml, those will then be passed to solr.
Jar up the FacetQueryProvider implementation and copy to tomcat/lib directory.
Custom-solr-facets-context.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<bean id="facet.dateFacetFields" class="org.springframework.beans.factory.config.SetFactoryBean">
<property name="sourceSet">
<set>
<value>#{http://www.alfresco.org/model/content/1.0}created</value>
<value>#{http://www.alfresco.org/model/content/1.0}modified</value>
<value>#{http://www.mycomp.com/model/hono/1.0}invoiceDate</value>
</set>
</property>
</bean>
<bean id="facet.dollarAmountBuckets" class="org.springframework.beans.factory.config.MapFactoryBean">
<property name="sourceMap">
<map>
<entry key="[0 TO 1000]" value="$0-$1K" />
<entry key="[1000 TO 10000]" value="$1K-$10K" />
<entry key="[10000 TO 100000]" value="$10K-$100K" />
<entry key="[100000 TO MAX]" value="Above.$100K" />
</map>
</property>
</bean>
<bean id="facet.dollarAmountDisplayHandler" class="com.mycomp.edm.alfresco.extensions.search.solr.facets.handlers.DollarAmountDisplayHandler" parent="baseFacetLabelDisplayHandler" >
<constructor-arg index="0">
<set>
<value>#{http://www.mycomp.com/model/hono/1.0}invoiceAmount</value>
</set>
</constructor-arg>
<constructor-arg index="1">
<ref bean="facet.dollarAmountBuckets" />
</constructor-arg>
</bean>
<bean id="facet.solrFacetHelper" class="org.alfresco.repo.search.impl.solr.facet.SolrFacetHelper" >
<constructor-arg>
<list>
<ref bean="facet.contentSizeBucketsDisplayHandler" />
<ref bean="facet.dateBucketsDisplayHandler" />
<ref bean="facet.dollarAmountDisplayHandler" />
</list>
</constructor-arg>
<property name="specialFacetIds">
<set>
<value>SITE</value>
<value>TAG</value>
<value>ANCESTOR</value>
<value>PARENT</value>
<value>ASPECT</value>
<value>TYPE</value>
<value>OWNER</value>
</set>
</property>
</bean>
</beans>
The model:
<?xml version="1.0" encoding="UTF-8"?>
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="hon:hono">
<description>hono model</description>
<author>amit</author>
<imports>
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
</imports>
<namespaces>
<namespace uri="http://www.mycomp.com/model/hono/1.0" prefix="hon"/>
</namespaces>
<data-types/>
<constraints/>
<types>
<type name="hon:invoice">
<title>Invoice</title>
<description>invoice model</description>
<parent>cm:content</parent>
<properties>
<property name="hon:invoiceNumber">
<title>Invoice Number</title>
<type>d:int</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>true</facetable>
</index>
</property>
<property name="hon:invoiceAmount">
<title>Invoice Amount</title>
<type>d:int</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>true</facetable>
</index>
</property>
<property name="hon:invoiceDate">
<title>Invoice Date</title>
<type>d:date</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>true</facetable>
</index>
</property>
<property name="hon:organizationName">
<title>Organization Name</title>
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>FALSE</tokenised>
<facetable>true</facetable>
</index>
</property>
<property name="hon:customerName">
<title>Customer Name</title>
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>FALSE</tokenised>
<facetable>true</facetable>
</index>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</type>
</types>
<aspects/>
</model>
Facet Query Provider
package com.mycomp.edm.alfresco.extensions.search.solr.facets.handlers;
import org.alfresco.repo.search.impl.solr.facet.FacetQueryProvider;
import org.alfresco.repo.search.impl.solr.facet.SolrFacetConfigException;
import org.alfresco.repo.search.impl.solr.facet.handler.AbstractFacetLabelDisplayHandler;
import org.alfresco.repo.search.impl.solr.facet.handler.FacetLabel;
import org.springframework.extensions.surf.util.ParameterCheck;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Amit on 2/24/16.
*/
public class DollarAmountDisplayHandler extends AbstractFacetLabelDisplayHandler implements FacetQueryProvider {
private static final Pattern SIZE_RANGE_PATTERN = Pattern.compile("(\\[\\d+\\sTO\\s(\\d+|MAX)\\])");
private final Map<String, FacetLabel> facetLabelMap;
private final Map<String, List<String>> facetQueriesMap;
public DollarAmountDisplayHandler(Set<String> facetQueryFields, LinkedHashMap<String, String> dollarValueBucketMap)
{
System.out.println("instantiating bean DollarAmountDisplayHandler");
ParameterCheck.mandatory("facetQueryFields", facetQueryFields);
ParameterCheck.mandatory("dollarValueBucketMap", dollarValueBucketMap);
this.supportedFieldFacets = Collections.unmodifiableSet(facetQueryFields);
facetLabelMap = new HashMap<>(dollarValueBucketMap.size());
Map<String, List<String>> facetQueries = new LinkedHashMap<>(facetQueryFields.size());
for (String facetQueryField : facetQueryFields)
{
List<String> queries = new ArrayList<>();
int index = 0;
for (Map.Entry<String, String> bucket : dollarValueBucketMap.entrySet())
{
String sizeRange = bucket.getKey().trim();
Matcher matcher = SIZE_RANGE_PATTERN.matcher(sizeRange);
if (!matcher.find())
{
throw new SolrFacetConfigException(
"Invalid dollar value range. Example of a valid size range is: [0 TO 1000]");
}
// build the facet query. e.g. {http://www.mycomp.com/model/hono/1.0}invoiceAmount:[0 TO 1000]
String facetQuery = facetQueryField + ':' + sizeRange;
queries.add(facetQuery);
// indexOf('[') => 1
String sizeRangeQuery = sizeRange.substring(1, sizeRange.length() - 1);
sizeRangeQuery = sizeRangeQuery.replaceFirst("\\sTO\\s", "\"..\"");
facetLabelMap.put(facetQuery, new FacetLabel(sizeRangeQuery, bucket.getValue(), index++));
}
facetQueries.put(facetQueryField, queries);
}
this.facetQueriesMap = Collections.unmodifiableMap(facetQueries);
System.out.println("Bean DollarAmountDisplayHandler instantiated");
}
#Override
public FacetLabel getDisplayLabel(String value)
{
FacetLabel facetLabel = facetLabelMap.get(value);
return (facetLabel == null) ? new FacetLabel(value, value, -1) : facetLabel;
}
#Override
public Map<String, List<String>> getFacetQueries()
{
return this.facetQueriesMap;
}
}

spring mvc send email (javamail) exception not getting caught

I am trying to send an email but before I was getting a nullpointerexception error which was due to mailSender not getting set correctly, now I edited the code as it is shown below and I am not getting any exception but the code breaks at the line
MimeMessage message = mailSender.createMimeMessage();
Here is my code (both sendMail() and addNewAlarm() are inside the same class "ElementService"):
public class ElementService implements ApplicationContextAware {
private ApplicationContext ac;
public void sendMail(String toAddress, String subject, String body) throws Exception{
JavaMailSender mailSender = (JavaMailSender) ac.getBean("mailSender");
MimeMessage message = mailSender.createMimeMessage();
try{
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("xxx#gmail.com");
helper.setTo(toAddress);
helper.setSubject(subject);
helper.setText(body);
}catch (MessagingException e) {
throw new MailParseException(e);
}
try{
mailSender.send(message);
}
catch(Exception e){
throw e;
}
}
//I want an email to be sent every 30 seconds
#Scheduled(fixedDelay = 30*1000)
public void function2RepeatEvery30Seconds()
{
MailService mailer = (MailService) ac.getBean("mailService");
mailer.sendMail("xxx#hotmail.com","subject","body");
//does other stuff..
}
#Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
this.ac = ac;
}
}
These are the beans in my xml:
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- SMTP settings -->
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="***#gmail.com" />
<property name="password" value="*****" />
<property name="javaMailProperties">
<!-- additional properties specific to JavaMail -->
<props>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
In debug mode I can see that mailSender has been set according to the properties shown on the mailSender bean.
I finally did it!! Thanks to Serge Ballesta of course. I should have been using log4j all along... I researched the Exception MessageRemovedIOException and I found this post java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger for JUnit test case for Java mail where there is a suggestion in the comments to change
<dependency> <groupId>javax.mail</groupId> <artifactId>javax.mail-api</artifactId> <version>1.5.2</version> </dependency>
to
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.5.2</version> </dependency>
I also had to change this:
<prop key="mail.smtp.starttls.enable">true</prop>
to this:
<prop key="mail.smtp.starttls.enable">false</prop>
Thank you very much for your time and advice #Serge Ballesta!
Ok, obviously the mailSender is null which causes the error. My guess would be that your #Autowired annotation is not processed. Do you have AutowiredAnnotationBeanPostProcessor registered? You can do that for example by using <context:annotation-config /> in your Spring configuration.
Other option (without using #Autowired) is to manually specify the dependency on mailSender in your mailService bean definition like so:
<bean id="mailService" class="gr.mobics.allweb.service.MailService" scope="singleton">
<property name="mailSender" ref="mailSender" />
</bean>
I have not tested this, but it seems like this is the cause of your problem. If these solutions don't work you, leave a comment and I'll try to update the answer.

Openejb with JPA - able to retrieve but cannot insert into database

I am using openejb as my standalone container to run my unit testcases, in all the test in all the tests i was able to retrieve the values but not able to insert or update. Even if i try entitymanager.merge(obj), it is selecting the value correctly but it is not updating it.
I am new to this , so please help me with this error
thanks in advance
my persistence.xml file
<persistence-unit name="test"
transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/OracleDS</jta-data-source>
.....entity classes.....
<properties>
<property name="eclipselink.target-server" value="JBoss" />
<property name="eclipselink.target-database" value="Oracle" />
<property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.logging.parameters" value="true" />
</properties>
</persistence-unit>
my dao method
tp.setname("van");
tp.settype("vehicle");
//entityManager.getTransaction().begin();
entityManager.merge(tp);
//entityManager.getTransaction().commit();
Do the followings for
Persist new entity:
Transport tp = new Transport();
tp.setname("van");
tp.settype("vehicle");
entityManager.getTransaction().begin();
entityManager.persist(tp);
entityManager.getTransaction().commit();
Update existing entity:
Query qry = entityManager.createQuery("Select t from
Transport t where t.type ='vechicle'");
List list = qry.getResultList();
//assume result return single entity
Transport tp = list.get(0);
tp.setInspectionDone(new Date()) ;
entityManager.getTransaction().begin();
entityManager.merge(tp);
entityManager.getTransaction().commit();
I think you need to ad #Transactional annotation in your class or method