Foren

Overriding service impl code in LR7

David Weitzel, geändert vor 6 Jahren.

Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
I have an existing EXT plugin from 6.2 that has to be replicated under Liferay DXP. It replaced the protected method validateScreenname() in the UserLocalServiceImpl class.
I have tried to use a serviceWrapper module to do this but that doesn't seem to work as the method is protected and the UserLocalServiceServiceWrapper obviously doesn't have that method to override.

so how can I override one method, or if necessary the whole Impl class?
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
Hey, Dave, what change are you trying to affect?










Come meet me at the 2017 LSNA!
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
We need to allow email addresses as screennames I know that screws up the personal sites url but that feature isn't being planned on being used.
This is done in the validateScreename method called from a number of services.
in particular we want to by-pass this check:

if (!Validator.isChar(c) && !Validator.isDigit(c) &&
					(c != CharPool.DASH) && (c != CharPool.PERIOD) &&
					(c != CharPool.UNDERLINE)) 


User defined validators will still go through this.
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
What version are you looking at, Dave? I'm going through the source for the method in SP19 and I'm not finding that code...








Come meet me at the 2017 LSNA!
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
Wow you are right, however the issue still remains but the solution must be elsewhere. If I try and set an email I get this exception reported:
The screen name cannot be an email address or a reserved word, such as postfix. It must contain only alphanumeric or the following special characters: -._@.

(I put " users.screen.name.special.characters=-._@ " in portal-ext.properties

Is this coming from the LayoutFriendlyURL validation then in which case we still have to overwrite that somehow.

Navigating the new source is pretty cumbersome, I guess the real question is how do we configure DXP for email formatted screennames?
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
You should just need to register a custom ScreenNameValidator that allows for the change you need. You're probably using the default screen name validator which is preventing those.

The default validator, com.liferay.portal.kernel.security.auth.DefaultScreenNameValidator, has specific code in place to fail validation if the screen name is an email address.

To do a custom one, you just need a bundle that has an @Component that implements the ScreenNameValidator interface; I'd recommend using a declared service ranking so your should be selected over the default.






Come meet me at the 2017 LSNA!
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
It seems that the portal.properties setting
users.screen.name.validator=com.liferay.portal.security.auth.LiberalScreenNameValidator

does nothing the exception is coming from the DefaultScreenNameValidator which does do an explicit email address check :
Validator.isEmailAddress(screenName)

There is no such check in the LiberalScreenValidator but that isn't being activated by the factory for some reason? is tis an matter of sort ordering in the registry?

Would love to know how to override this
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Just want to jump in at this point to highlight something from my past with this. I went down this path once (in 6.2 EE) with a customer of mine and even went as far as to open a ticket because I thought I had found a bug. I set the LiberalScreenNameValidator as well and found the same thing... there aren't supposed to be any restrictions but I couldn't get past with certain characters. I don't recall the exact line number, but if yo ulook inside the UserLocalServiceImpl, you'll find a point where a validate screenname or some such thing is called. That validation is performed regardless of the screen name validator logic and actually enforces the same rules as the default validator (if memory serves).

The LESA was closed as "not a bug" and the reason I was given was that it has to do with characters that are also valid for urls. It was pointed out that you could have user/{screenname} as the url pattern for a users private site -- so things like an @ sign wouldn't fly. I tried to argue that if you had user sites disabled then it shouldn't matter but at that stage both I and LESA had taken our stance emoticon. In the end, we were forced to find another solution.

I doubt this helps -- but you would probably have to override several core services to do what you are trying to do.
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
@Andrew That's still in there...

I see that it will not allow all numbers unless the users.screen.name.allow.numeric property is set. Even when it is allowed, the number cannot match a group id, although it can be the same ID as your user id.

Next it filters out anonymous names (guest, anonymous, those kinds of things).

Next it filters out matches to existing screen names and groups.

Next it verifies the friendly url based off of the screen name is valid (for reasons that were already shared).

And finally it filters out any reserved screen names.

Note that for your email address as screen name issue, Liferay basically determines the friendly URL as "/" + the screen name. When that validates against "/test@liferay.com", of course it is going to fail. However, if you did a service wrapper around UserLocalService to URL-encode the screen name before passing into the real UserLocalService, then the "/test%40liferay.com" would likely be okay, although this may have other effects that you don't care for.






Come meet me at the 2017 LSNA!
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
Ah, yeah, so with Liferay 7 CE/Liferay DXP, many of the old portal-ext.properties values don't work anymore. Many have been moved to OSGi properties or simply don't apply anymore since OSGi service trackers can pick the right implementation to use.

In fact, if you check the portal source for that property, you see:

# Input a class name that implements
# com.liferay.portal.security.auth.ScreenNameValidator. This class will be
# called to validate user screen names.
#
# This property is not read by the portal except for portal properties
# overridden by liferay-hook.xml. It remains here only as a reference.
#
#users.screen.name.validator=com.liferay.portal.security.auth.DefaultScreenNameValidator
#users.screen.name.validator=com.liferay.portal.security.auth.LiberalScreenNameValidator


The important part there is the note about overriding in portal properties in a hook. So basically they're saying the property only works if you're trying to deploy a legacy hook war into Liferay, otherwise the property does not apply.

It may be supported in the system settings control panel, but a quick search didn't seem to find one that jumped out, although I did not spend more than 20 seconds looking emoticon






Come meet me at the 2017 LSNA!
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
Hi David
I haven't noticed on the few upgrade test we have done any report of portal-ext properties that need review/alternative approaches
Is there a reference to what won't work from portal-ext any more?

Quick question will old fashioned WAR hook work in DXP for simple things such as

a) Override portal.properties
b) Language.properties (and translations)
c) core jsp overrides?

By old fashioned I mean driven by liferay-hook.xml file and associated files /folder references in that. using the old New> Liferay Plugin> options in the IDE and maven or ant t o build a war file?

If not what type of osgi module do I use? I can see that for some properties - eg autologin hooks etc using osgi to build the final list of hooks to use is better than the 6.2 system as neither portal-ext or the hook could be deployed without some error of a referenced class not found unless things were deployed in a particular order which you couldn't dictate
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
David Weitzel:
Is there a reference to what won't work from portal-ext any more?


There may be one somewhere in dev.liferay.com, but I'm not aware of one.

Quick question will old fashioned WAR hook work in DXP for simple things such as

a) Override portal.properties
b) Language.properties (and translations)
c) core jsp overrides?


Sort of? I mean, I know there's stuff in the code base for legacy hook wars, but I honestly don't know how good the support is. Core JSP overrides, for example, is a loaded question because Asset Publisher JSPs, for example, used to be core but now they are not, so they're not covered, but the portal does still have some JSPs that are core but there's a new mechanism that is supposed to be used for those, ...

If not what type of osgi module do I use? I can see that for some properties - eg autologin hooks etc using osgi to build the final list of hooks to use is better than the 6.2 system as neither portal-ext or the hook could be deployed without some error of a referenced class not found unless things were deployed in a particular order which you couldn't dictate


There's not a 1-to-1 mapping across the board as far as I'm aware. I would recommend reviewing this: https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/from-liferay-6-to-liferay-7. It's becoming a good source of details of 6 to 7 migration, I believe there was a table documenting common migration strategies that may actually help with specific upgrades....










Come meet me at the 2017 LSNA!
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
Hi David or anyone else.
So the objective is still the same - allow email address as a screenName
From what I can ascertain we need to:
a) change the ScreenNameValidator to the LiberalScreenNameValidator - fixes the javascript validation
b) override either the userLocalServiceImpl or may be the LayoutImpl to allow Email address (@ sign in particular) in the friendlyURl since we will not be using user pages

A) I cannot find any example code to show how you override portal.properties in a module? Do I have to use a hook in which case how is one built using the current DXP IDE?

BTW the value in the commented out portal.properties is wrong it is :users.screen.name.validator=com.liferay.portal.kernel.security.auth.LiberalScreenNameValidator

B ) Can I override a Model Impl using osgi module as the LayoutImpl is where the exception gets thrown it is better to fix there. If so is there an example anywhere?
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
David Weitzel:
So the objective is still the same - allow email address as a screenName


Based on the review of the stuff Andrew pointed out, it's simply not going to be possible.

Liferay uses the screen name as part of the friendly URL for accessing the user's public and private pages; even if you disable these, the friendly url check still applies.

Through the wrapper I mentioned, you could force the screen name to be a URL encoded name and that would likely pass the check on friendly url, but it does get away from email address as screen name.









Come meet me at the 2017 LSNA!
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Can I ask a question -- why do you need to store an email address in the screenname field for the user object? Why can't you store the value in the email address field?

Maybe if you can give us a little more background on the problem you are trying to solve we can propose an alternate solution that doesn't require changing the portal core services and can still meet your business requirements.
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
we are using a SSO solution which has for some time allowed screenname with email addresses as the user id.

Most users don't use their email address - typically using their LAN-Id for logging in to windows as that is more common across business applications. The service is used by 40 different organizations on an extranet. (Not accessible from internet).

The service was using these identities before they switched to Liferay 6 or more years ago. They use Siteminder and now switching to Okta SSO.

A EXT was developed to handle this in 6.1 and 6.2. It went into the userLocalServiceImpl.validateScreenName() code and skipped the character check that is also done by the external validator (or not depending which one you configure) and also skipped the FreindlyURL check.

All we want to do in DXP is do what we could do in the 6.2 EXT as we upgrade to DXP before delivering some advanced functionality
thumbnail
David H Nebinger, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 14919 Beitrittsdatum: 02.09.06 Neueste Beiträge
David Weitzel:
All we want to do in DXP is do what we could do in the 6.2 EXT as we upgrade to DXP before delivering some advanced functionality


In DXP, the EXT plugin support has been restored (or at least that's my understanding emoticon) so you should be able to provide a modified version of the UserLocalServiceImpl class.








Come meet me at the 2017 LSNA!
thumbnail
Christoph Rabel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 1554 Beitrittsdatum: 24.09.09 Neueste Beiträge
Couldn't you just write a AutoLogin module? Several of my customers use some kind of SSO solution that sets headers. I guess Okta SSO does the same as Siteminder and writes the userid or in your case emailaddress in a header.

We wrote our own autologin modules for 6.0, 6.1, 6.2. It's quite easy to do that. And soon we will have to port them to Liferay 7.
https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/auto-login

Basically we do this:
getUserFromHeader
findUserSomehow
if (user == null) createUser(...),
return userId;

You just need to make sure that the findUser method is able to find the user with the SSO ID. e.g. you could encode the emailaddress Base64 and set it as screenname in the creation method. Or write the Id in a custom field. That way you can write whatever you want into the Liferay user, completely independent from the ids you get from SSO. You just somehow need to match them.
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Bingo -- thumbs up on this response Christoph. Sounds to me like the original solution was a bad one that just kept getting ported from version to version. AutoLogin, I would agree, is the right solution to solve this problem -- and much easier to move to the next version than an EXT plugin would be.
David Weitzel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Junior Member Beiträge: 65 Beitrittsdatum: 07.10.15 Neueste Beiträge
Been distracted by other upgrade issues.

This idea looks promising

Would this encoding the sso userid (which an be but isn't always an email address) allow for existing screennames that are not encoded?

we are doing our own auto login (using headers set from the SSO attributes) so would be easy when creating users to set it that way, I guess we can put logic that checks the original version and the base 64 and updates every one to base 64?
final thought when using the user interface I know we can disable the field so it cant be updated or should we modify the userLocaService updateUser code to check it is encoded?
thumbnail
Christoph Rabel, geändert vor 6 Jahren.

RE: Overriding service impl code in LR7

Liferay Legend Beiträge: 1554 Beitrittsdatum: 24.09.09 Neueste Beiträge
Well, you can pretty much store the mapping wherever you want. The base64 approach was just a quick idea. If you have constraints on screenname, then don't use the field. You probably could store your ID in any field and use search to find it. Or use an existing field like UUID. Or maybe OpenID.

You could also create mapping table which stores your ID and the Liferay userId. In the end you just have to be able to map your user to a liferay user.