Skip to content

Commit 6d3159f

Browse files
authored
Merge pull request #36 from ktor/master
feat: company settings -> service access policies
2 parents 6609067 + 83a0dc6 commit 6d3159f

File tree

12 files changed

+364
-78
lines changed

12 files changed

+364
-78
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build and analyze
1+
name: Build and test
22
on:
33
push:
44
branches:
@@ -7,7 +7,7 @@ on:
77
types: [ opened, synchronize, reopened ]
88
jobs:
99
build:
10-
name: Build and test
10+
name: Maven clean package
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v2
@@ -33,33 +33,3 @@ jobs:
3333
env:
3434
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
3535
run: mvn -B clean package
36-
scan:
37-
name: Analyze
38-
runs-on: ubuntu-latest
39-
steps:
40-
- uses: actions/checkout@v2
41-
with:
42-
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
43-
- name: Set up JDK 11
44-
uses: actions/setup-java@v1
45-
with:
46-
java-version: 11
47-
- name: Cache Maven packages
48-
uses: actions/cache@v1
49-
with:
50-
path: ~/.m2
51-
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
52-
restore-keys: ${{ runner.os }}-m2
53-
- name: Cache SonarCloud packages
54-
uses: actions/cache@v1
55-
with:
56-
path: ~/.sonar/cache
57-
key: ${{ runner.os }}-sonar
58-
restore-keys: ${{ runner.os }}-sonar
59-
- name: Sonar Scan
60-
env:
61-
# Needed to get some information about the pull request, if any
62-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63-
# SonarCloud access token should be generated from https://sonarcloud.io/account/security/
64-
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
65-
run: mvn -B verify -DskipTests org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Pcoverage

README.adoc

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
= Liferay Portal DB setup core
22
:liferay-version: 7.3.6
3-
:current-db-setup-core-version: 7.3.603
3+
:current-db-setup-core-version: 7.3.604
44
:TOC:
55

66
image:https://maven-badges.herokuapp.com/maven-central/com.ableneo.liferay/com.ableneo.liferay.db.setup.core/badge.svg?color=blue[Maven Central,link=https://search.maven.org/search?q=g:com.ableneo.liferay%20AND%20a:com.ableneo.liferay.db.setup.core]
@@ -11,11 +11,13 @@ Library that allows to setup a number of https://github.com/liferay[Liferay] art
1111

1212
== Usage
1313

14-
We recommend wrapping the library calls in either Liferay *upgrade process* or in a control panel app for a *reset to defaults* application.
14+
We recommend using Liferay's link:https://learn.liferay.com/dxp/latest/en/building-applications/data-frameworks/upgrade-processes.html[upgrade process] or control panel portlet to apply declared database changes.
1515

16-
=== Examples
17-
==== Configuration
18-
All data definitions in examples are applied according to XML file header which defines on which company data creation should take effect and which admin user should be used for data creation.
16+
=== Configuration header
17+
All data definitions in the setup XML file are applied according to the `configuration` header. The header defines:
18+
19+
. the link:https://learn.liferay.com/dxp/latest/en/system-administration/configuring-liferay/virtual_instances.html[virtual instance] on which the library will modify the data.
20+
. admin user account to be used for data modification
1921

2022
.Automatically selected admin user
2123
[source, xml]
@@ -29,6 +31,7 @@ All data definitions in examples are applied according to XML file header which
2931
<companywebid>liferay.com</companywebid>
3032
</company>
3133
</configuration>
34+
</setup>
3235
----
3336

3437
.Specified admin user
@@ -44,7 +47,38 @@ All data definitions in examples are applied according to XML file header which
4447
</company>
4548
</configuration>
4649
----
50+
=== Features
51+
52+
==== Service Access Policy
53+
link:https://learn.liferay.com/dxp/latest/en/installation-and-upgrades/securing-liferay/securing-web-services/setting-service-access-policies.html#[Service access policy] is a link:https://learn.liferay.com/dxp/latest/en/installation-and-upgrades/securing-liferay/securing-web-services.html[second] from four of Liferay's API security layers. Together with _IP Permission Layer_, _Authentication and verification layer_ and _User permission layer_ is responsible for securing access to web services provided by portal instance.
54+
55+
If you develop new link:https://learn.liferay.com/dxp/latest/en/headless-delivery/apis-with-rest-builder.html[REST Builder] REST/GraphQL endpoint's it's a common requirement to setup an access for those API's for an unauthenticated portal user- Guest which is by default forbidden.
56+
57+
.Add new or update existing Service Access Policy by name
58+
[source, xml]
59+
----
60+
<company-settings>
61+
<service-access-policies>
62+
<service-access-policy name="MY_ACCESS_POLICY" enabled="true" unauthenticated="true">
63+
<title locale="sk_SK" text="Moja pristupova politika" />
64+
<allowed-service-signatures> <1>
65+
com.liferay.headless.admin.user.internal.resource.v1_0.SiteResourceImpl#getSite
66+
</allowed-service-signatures>
67+
</service-access-policy>
68+
</service-access-policies>
69+
</company>
70+
----
71+
<1> `allowed-service-signatures` provides the same functionality as link:https://learn.liferay.com/dxp/latest/en/installation-and-upgrades/securing-liferay/securing-web-services/setting-service-access-policies.html#creating-a-service-access-policy[_Advanced Mode_]
4772

73+
.Delete existing Service Access Policy by name
74+
[source,xml]
75+
----
76+
<company-settings>
77+
<service-access-policies>
78+
<delete-service-access-policy name="WIZARD_GUEST_ACCESS"/>
79+
</service-access-policies>
80+
</company-settings>
81+
----
4882
==== Permissions
4983
Resource permissions.
5084
[source, xml]
@@ -256,6 +290,13 @@ They are probably not perfect, please let me know if anything feels wrong or inc
256290

257291
== Changelog
258292

293+
=== Version 7.3.604
294+
==== Features & bug fixes
295+
* added an ability to create/update/delete link:https://learn.liferay.com/dxp/latest/en/installation-and-upgrades/securing-liferay/securing-web-services/setting-service-access-policies.html[Service Access Policies]
296+
297+
==== Refactorings & project changes
298+
* refactored common mock setup into a separate class
299+
259300
=== Version 7.3.603
260301
==== Features & bug fixes
261302
* fixed setup for multiple companies/groups

pom.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,18 @@
225225
<plugin>
226226
<groupId>com.hubspot.maven.plugins</groupId>
227227
<artifactId>prettier-maven-plugin</artifactId>
228-
<version>0.12</version>
228+
<version>0.17</version>
229229
<configuration>
230+
<prettierJavaVersion>1.6.1</prettierJavaVersion>
231+
<printWidth>120</printWidth>
232+
<useTabs>false</useTabs>
233+
<tabWidth>4</tabWidth>
230234
<ignoreConfigFile>false</ignoreConfigFile>
231235
<ignoreEditorConfig>false</ignoreEditorConfig>
236+
<inputGlobs>
237+
<inputGlob>src/main/java/**/*.java</inputGlob>
238+
<inputGlob>src/test/java/**/*.java</inputGlob>
239+
</inputGlobs>
232240
</configuration>
233241
</plugin>
234242

src/main/java/com/ableneo/liferay/portal/setup/LiferaySetup.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.ableneo.liferay.portal.setup.core.SetupPermissions;
77
import com.ableneo.liferay.portal.setup.core.SetupPortal;
88
import com.ableneo.liferay.portal.setup.core.SetupRoles;
9+
import com.ableneo.liferay.portal.setup.core.SetupServiceAccessPolicies;
910
import com.ableneo.liferay.portal.setup.core.SetupSites;
1011
import com.ableneo.liferay.portal.setup.core.SetupUserGroups;
1112
import com.ableneo.liferay.portal.setup.core.SetupUsers;
@@ -14,6 +15,7 @@
1415
import com.ableneo.liferay.portal.setup.domain.CustomFields;
1516
import com.ableneo.liferay.portal.setup.domain.ObjectsToBeDeleted;
1617
import com.ableneo.liferay.portal.setup.domain.Organization;
18+
import com.ableneo.liferay.portal.setup.domain.ServiceAccessPolicies;
1719
import com.ableneo.liferay.portal.setup.domain.Setup;
1820
import com.ableneo.liferay.portal.setup.domain.Site;
1921
import com.liferay.portal.kernel.exception.PortalException;
@@ -120,6 +122,15 @@ public static boolean setup(final Setup setup, Bundle callerBundle) {
120122
SetupConfigurationThreadLocal.configureThreadLocalContent(runAsUserEmail, companyId, callerBundle);
121123
executeSetupConfiguration(setup);
122124

125+
// setup company settings
126+
if (setup.getCompanySettings() != null) {
127+
// setup service access policies
128+
final ServiceAccessPolicies serviceAccessPolicies = setup.getCompanySettings().getServiceAccessPolicies();
129+
if (serviceAccessPolicies != null) {
130+
SetupServiceAccessPolicies.setupServiceAccessPolicies(serviceAccessPolicies);
131+
}
132+
}
133+
123134
// iterate over group names or choose GUEST group for the company
124135
if (company.getGroupName().isEmpty()) {
125136
company.getGroupName().add(GroupConstants.GUEST);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.ableneo.liferay.portal.setup.core;
2+
3+
public abstract class AbstractSetup {
4+
5+
private AbstractSetup() {}
6+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package com.ableneo.liferay.portal.setup.core;
2+
3+
import com.ableneo.liferay.portal.setup.SetupConfigurationThreadLocal;
4+
import com.ableneo.liferay.portal.setup.domain.DeleteServiceAccessPolicy;
5+
import com.ableneo.liferay.portal.setup.domain.ServiceAccessPolicies;
6+
import com.ableneo.liferay.portal.setup.domain.ServiceAccessPolicy;
7+
import com.liferay.portal.kernel.exception.PortalException;
8+
import com.liferay.portal.kernel.service.ServiceContext;
9+
import com.liferay.portal.kernel.util.LocaleUtil;
10+
import com.liferay.portal.security.service.access.policy.exception.NoSuchEntryException;
11+
import com.liferay.portal.security.service.access.policy.model.SAPEntry;
12+
import com.liferay.portal.security.service.access.policy.service.SAPEntryLocalServiceUtil;
13+
import java.util.HashMap;
14+
import java.util.List;
15+
import java.util.Locale;
16+
import java.util.Map;
17+
import org.slf4j.Logger;
18+
import org.slf4j.LoggerFactory;
19+
20+
public class SetupServiceAccessPolicies {
21+
22+
private static final Logger LOG = LoggerFactory.getLogger(SetupCategorization.class);
23+
24+
public static void setupServiceAccessPolicies(ServiceAccessPolicies serviceAccessPolicies) {
25+
final List<ServiceAccessPolicy> serviceAccessPolicyList = serviceAccessPolicies.getServiceAccessPolicy();
26+
27+
final Long runInCompanyId = SetupConfigurationThreadLocal.getRunInCompanyId();
28+
serviceAccessPolicyList.forEach(serviceAccessPolicyConfiguration -> {
29+
Map<Locale, String> titleMap = new HashMap<>();
30+
serviceAccessPolicyConfiguration
31+
.getTitle()
32+
.forEach(title -> {
33+
titleMap.put(LocaleUtil.fromLanguageId(title.getLocale()), title.getText());
34+
});
35+
36+
SAPEntry sapEntry = getSapEntry(runInCompanyId, serviceAccessPolicyConfiguration.getName());
37+
38+
if (sapEntry == null) {
39+
addSAPEntry(serviceAccessPolicyConfiguration, titleMap);
40+
} else {
41+
sapEntry.setEnabled(serviceAccessPolicyConfiguration.isEnabled());
42+
sapEntry.setDefaultSAPEntry(serviceAccessPolicyConfiguration.isUnauthenticated());
43+
sapEntry.setAllowedServiceSignatures(serviceAccessPolicyConfiguration.getAllowedServiceSignatures());
44+
if (!titleMap.isEmpty()) {
45+
sapEntry.setTitleMap(titleMap);
46+
}
47+
updateSAPEntry(sapEntry);
48+
}
49+
});
50+
51+
final List<DeleteServiceAccessPolicy> deleteServiceAccessPolicyList = serviceAccessPolicies.getDeleteServiceAccessPolicy();
52+
deleteServiceAccessPolicyList.forEach(deleteServiceAccessPolicy -> {
53+
final SAPEntry sapEntry = getSapEntry(runInCompanyId, deleteServiceAccessPolicy.getName());
54+
if (sapEntry != null) {
55+
deleteSAPEntry(sapEntry);
56+
} else {
57+
LOG.warn("Tried to delete SAP Entry {} in company {} but the entry haven't been found.", deleteServiceAccessPolicy.getName(), runInCompanyId);
58+
}
59+
});
60+
}
61+
62+
private static void deleteSAPEntry(SAPEntry sapEntry) {
63+
try {
64+
SAPEntryLocalServiceUtil.deleteSAPEntry(sapEntry);
65+
} catch (PortalException e) {
66+
LOG.error(
67+
"Unexpected exception when trying to delete SAP Entry {} in company {}",
68+
sapEntry.getName(),
69+
sapEntry.getCompanyId(),
70+
e
71+
);
72+
}
73+
}
74+
75+
protected static void updateSAPEntry(SAPEntry sapEntry) {
76+
SAPEntryLocalServiceUtil.updateSAPEntry(sapEntry);
77+
}
78+
79+
protected static void addSAPEntry(
80+
ServiceAccessPolicy serviceAccessPolicyConfiguration,
81+
Map<Locale, String> titleMap
82+
) {
83+
final ServiceContext serviceContext = new ServiceContext();
84+
serviceContext.setCompanyId(SetupConfigurationThreadLocal.getRunInCompanyId());
85+
final Long runAsUserId = SetupConfigurationThreadLocal.getRunAsUserId();
86+
try {
87+
SAPEntryLocalServiceUtil.addSAPEntry(
88+
runAsUserId,
89+
serviceAccessPolicyConfiguration.getAllowedServiceSignatures(),
90+
serviceAccessPolicyConfiguration.isUnauthenticated(),
91+
serviceAccessPolicyConfiguration.isEnabled(),
92+
serviceAccessPolicyConfiguration.getName(),
93+
titleMap,
94+
serviceContext
95+
);
96+
} catch (PortalException e) {
97+
LOG.error(
98+
"Unexpected exception trying to add SAP Entry {} to company {} with a user {}",
99+
serviceAccessPolicyConfiguration.getName(),
100+
serviceContext.getCompanyId(),
101+
runAsUserId,
102+
e
103+
);
104+
}
105+
}
106+
107+
protected static SAPEntry getSapEntry(Long companyId, String name) {
108+
try {
109+
return SAPEntryLocalServiceUtil.getSAPEntry(companyId, name);
110+
} catch (NoSuchEntryException e) {
111+
LOG.debug("SAP Entry {} not found in company {}", name, companyId);
112+
} catch (PortalException e) {
113+
LOG.error("Unexpected exception when trying to fetch SAP Entry {} from company {}", name, companyId);
114+
}
115+
116+
return null;
117+
}
118+
}

0 commit comments

Comments
 (0)