Giving no-admin users access to Template module - typo3

I'm setup a TYPO3 website and I need to give a user group the permission to view and edit to the Template module.
On the TYPO3 documentation I found this information :
If you cannot see the Template module, it may be that you are not
logged in as an administrator. Please change user and make sure you
use one with administrator rights.
There is no a work-around to give backend users access to the Template
module ?

No possibility except you xclass core methods.
Maybe there is another solution to your problem.
Please state why an editor should have access to the template module.

I was able to make the "Web -> Template" module accessible to non-administrators
typo3\sysext\frontend\Configuration\TCA\sys_template.php
Change line 16:
'adminOnly' => true,
to
'adminOnly' => false,
Now, you can Edit Backend usergroup and check the option Template [sys_template] on Tables (listing) and Tables (modify)

Related

TYPO3: How to use an external PHP Script (in fileadmin), where i can check the cookie

I'm using TYPO3 11.3.3 for my server and i need a PHP Script, that can read and check the typo3_fe cookie. Are there any solutions? I can't use an extension and I have to keep it simple.
What exactly should the PHP script do apart from reading the cookie?
You can use a TypoScript condition to check if the cookie is present:
[request.getCookieParams()['foo'] == 1]
See the documentation for details.
The only way would be a content object USER. Check out the documentation.
Example
page = PAGE
page.10 = USER_INT
page.10 {
userFunc = Vendor\ExtensionName\ExampleTime->printTime
}
However the doc also states
The property includeLibs has been removed in TYPO3 8.0. In earlier
versions the userFunc classes were sometimes stored in fileadmin/ -
this is no longer possible out of the box and not recommended.
For the best result you should always, without exception, place your
class files in an extension, define composer class loading for this
extension and add this extension as a dependency of your project.
Then, your classes will load without issues when you refer to them by
their class name.
Cookies are being sent along with the request. With that being said, the best way to check for the cookies is Middlewares. With the middlewares you can check for the sent cookies and evaluate them with your script.
Here is the documentation about middlewares.
This might be helpful as well https://stackoverflow.com/a/63951593/7162477
Best regards

Backpack with Multi tenancy

i am creating an ERP system with multi tenant with different db and has sub-domain for tenants.
i am using the stancl\tenancy for the multi tenant package
I have a main domain for creating and adding companies
Normally, when i load users in my tenant's sub-domains ex.(foo.maindomain.com), it is only showing the users table in the tenant's db. But with the backpack dashboard in permission manager it is showing the Users in the main database instead of the user in the tenant's own database.
Is there someone who has experience this and can help me with this problem?
your help will be much appreciated, Thank you in advance
The docs for that tenancy package show that they use a various middlewares that set the tenant for the application. Based on your question, Ill assume you're using the Subdomain identification middleware in your app.
The issue is most likely that your Backpack permissions routes are not using this middleware.
If we look at Backpack's docs, they say this about the permissions routes:
If you need to modify how this works in a project:
create a routes/backpack/permissionmanager.php file; the package will see that, and load your routes file, instead of the one in the package;
To fix the issue, create a file at allin.com/routes/backpack/permissionmanager.php copy the contents from vendor/backpack/permissionmanager/src/routes/backpack/permissionmanager.php, paste that in the new file and add the middleware needed for the tenancy app, which should look something like:
Route::group([
'namespace' => 'Backpack\PermissionManager\app\Http\Controllers',
'prefix' => config('backpack.base.route_prefix', 'admin'),
'middleware' => ['web', InitializeTenancyBySubdomain::class, backpack_middleware()],
], function () {
Route::crud('permission', 'PermissionCrudController');
Route::crud('role', 'RoleCrudController');
Route::crud('user', 'UserCrudController');
});

TYPO3 backend deeplink to page record

I am using version 8.7 of TYPO3 and intended to use a link that leads directly to the backend to edit a record (page). I tried anything like typo3/backend.php?edit=57 but got a error:
file not found
typo3/backend.php?edit=57 was the way to do it up until TYPO3 6.2, but the backend URL changed to typo3/index.php in TYPO3 7.6. It still works kind of, however you need a security token which is generated by the core. The URL now is typo3/index.php?route=%2Fmain&edit=57&token=.... There isn't really an easy way to generate URL with a valid token like that from outside TYPO3 though.
If you want to create a link inside a custom module to edit a record you can use \TYPO3\CMS\Backend\Utility\BackendUtility::editOnClick() or if you're using a Fluid template, the \TYPO3\CMS\Backend\ViewHelpers\Link\EditRecordViewHelper ViewHelper. More on that you can find here: https://docs.typo3.org/typo3cms/CoreApiReference/8.7/ApiOverview/Examples/EditLinks/
Using the extension pxa_siteimprove deep links are of the following form:
https://example.com/typo3/index.php?tx_siteimprove_goto=page:{page_uid}:{language_uid}
The parameter language_uid is optional. An example link to a page with uid 42 looks like this:
https://example.com/typo3/index.php?tx_siteimprove_goto=page:42
Optionally we can include a language uid (e.g. 1). Without a language uid set it defaults to 0:
https://example.com/typo3/index.php?tx_siteimprove_goto=page:42:1
If you want to create deep links for other purposes, you can look how this extension creates the deep link in Pixelant\PxaSiteimprove\Hooks\DeepLinkingHandler. In a first hook it just saves the page uid to the backend user session and in a later hook reuses this information to redirect to the desired page by setting the following global variable:
$GLOBALS['BE_USER']->uc['startModuleOnFirstLogin'] = 'web_layout->id=' . (int)$pageId . '&SET[language]=' . (int)$languageId;

Programmatically change user role in JBoss EAP 6.2

We are trying to get this working in JBoss EAP 6.2 but for the moment we haven't been able to find the reason why it is failing.
In our application, super users are able to decide which role they want to use after login in the application. So first the user will have a role and then we want to change it. For this we are doing the following:
Subject sub = (Subject) PolicyContext.getContext("javax.security.auth.Subject.container");
for (Principal p : sub.getPrincipals()) {
if ("Roles".equals(p.getName())) {
SimpleGroup group = (SimpleGroup) p;
group.removeMember(new SimplePrincipal(CONSTANT_SUPER_USER));
group.addMember(new SimplePrincipal(authorizationRole));
}
}
This is actually changing the role in the Subject. But afterwards when the authorization is being checked we get the following in the server's log:
[org.apache.catalina.authenticator] (http-/0.0.0.0:8080-11) We have cached auth type LOGIN for principal GenericPrincipal[userName(superuser,)]
As you can see, it is still getting the old value after modifying it.
We are using our own class extending SimplePrincipal. Checking the content of Faces.getRequest() we have seen that the request contains an userPrincipal of type JBossGenericPrincipal and inside it, it contains our extended SimplePrincipal. Checking both of them we have seen that:
JBossGenericPrincipal.roles contains superuser
JBossGenericPrincipal.subject.principals contains the modified SimpleGroup with the new authorization role
Just for your information, we had this working on Wildfly first and it worked perfectly, but we had to change to JBoss and found that this wasn't working properly. So we think it has to be something related to this specific JBoss version.
Has someone faced this problem? Any idea why this might be failing? I guess we need to put the correct role in JBossGenericPrincipal.roles somehow, but... how?
Any help is appreciated. Thanks!
Seems Red Hat doesn't recommend changing the roles after the authentication has been done. So the only solution was to logout and re-login the user with the new role.

Set Site Permissions for a Role Programmatically Liferay 6.2

I am creating a startup hook script for liferay to add and preconfigure Roles for Liferay 6.2 behind the scenes.
Specifically I am looking to add the type of permissions that can be accessed through Control Panel > Roles > Actions> Define Permissions.
Currently I am able to add Liferay Roles, but have so far been unsuccessful in finding the correct way to add custom permissions to the Roles programmatically. I see there was a way to do this in prior Liferay versions, but do not see it here.
https://www.liferay.com/community/forums/-/message_boards/message/2965424
https://www.liferay.com/web/guest/community/forums/-/message_boards/message/124558
So far I have investigated RolePermissionUtil, RoleLocalServiceUtil, among other available services.
Let me know if this is available through the service to be added to a startup hook or if this can only be done in the UI.
It appears that the API has changed since these posts.
Thank you in advance for your help
Figured it out using ResourcePermissionLocalServiceUtil.setResourcePermissions and RoleLocalServiceUtil.
Eg.
RoleLocalServiceUtil.fetchRole(CompanyThreadLocal.getCompanyId(), "Role Name");
ResourcePermissionLocalServiceUtil.setResourcePermissions(CompanyThreadLocal.getCompanyId(), Role.class.getName(), ResourceConstants.SCOPE_GROUP_TEMPLATE, String.valueOf(role.getRoleId()), role.getRoleId(), new String[] {ActionKeys.VIEW, ActionKeys.UPDATE, ActionKeys.DELETE});
I used CompanyThreadLocal to obtain the Company Id because I am using this in a hook not a portlet, where typically it would be accessed through the theme display. Here I am just adding access to Roles, but other class namespaces could be added. (eg. "com.liferay.portlet.dynamicdatalists.model.DDLRecordSet")