I do develop a little extension for a TYPO3 v10 where I need to gain access to the my extension-settings in a service class that extends \TYPO3\CMS\Core\Authentication\AuthenticationService.
My first attemp was to pass the settings using the DI configured in my Services.yaml according to: https://daniel-siepmann.de/concrete-typo3-dependency-injection-examples.html (Inject Extension Configuration)
However no matter what I do the settings array passed to my __constructor(array $settings) stays empty.
Then I tried to go for a more hacky attemp like:
public function __construct(array $settings)
{
$this->settings = $settings;
DebuggerUtility::var_dump($this->settings);
$configurationManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Configuration\ConfigurationManager::class);
$typoscript = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
DebuggerUtility::var_dump($typoscript);
die('debug');
}
But also loading the the full typoscript seems to fail since $typoscript is also null. Therefore I think that is has to do something with the AuthenticationService that my class extends? How can I gain access to my settings when extending TYPO3's AuthenticationService?
When the AuthenticationService is consulted for FE or BE login, typoscript is not available yet, as authentication happens early in the middleware stack (have a look at the order of the PSR-15 middlewares in the configuration module of the backend).
This is because typoscript is page dependend and whether you are eligible to access a page may be dependend on you login status or user roles.
So the question would be what kind of settings are you trying to access? You could use the site configuration (that is already loaded for authentication) or you could use global configuration in TYPO3_CONF_VARS that is always available.
Related
I am trying to make the configuration for Pusher in my Laravel app (SaaS) dynamic.
Basically I want to store different Pusher configs for different accounts. And call the corresponding config based on the user.
I have tries to change the config in runtime using config()->set('services.pusher.xxx', 'yyyy'), but this doesn't work at any level of the framework, event in a custom ServiceProvider.
I found Laravel's BroadcastManager and tried to override the createPusherDriver() so that I could create a custom instance of PusherBroadcaster with the user's config, but I am not sure how to do that or where to put it!
What is the best-practice/standard way to do that?
I've been using a setup like this in one of my own projects, to set a custom mail config:
NOTE: Your mileage may vary due to the order in which service providers are loaded in your app.
Create a serviceprovider like app\Providers\ConfigProvider.php
public function boot()
{
$this->app->booted(function () {
$shouldSetCustomConfig = true;
// Set config values from database.
if($shouldSetCustomConfig) {
config([
'mail.host' => Config::get('mail.host'),
'mail.port' => Config::get('mail.port'),
]);
}
});
}
The $this->app->booted() is a simple callback that gets called after the application has been booted. This might not always work correctly because I've seen various packages that use this callback too to do various stuff. When this is the case, the order of registration matters. Note that it is not required to use this callback. One might simply call the config(['key' => 'newval']) directly and it could work as intended.
The service provider above should be loaded BEFORE the provider you are setting configuration for. In the example above it would be the Illuminate\Mail\MailServiceProvider::class. This should make sure the correct config is loaded.
I want to make boot function for my app preview, for that I have plan to add new variable to .env file and let's name it APP_Mode so I want to say:
If APP_Mode=preview prevent all actions and redirect back with
xxxxxx text as flash session message.
The point
The point of this boot action that I try to achieve is to not let users change any of my preview site settings like store/delete/update etc.
Question
Is that possible? How?
First off, might be worth considering if Laravel's maintenance mode might work for you - you can whitelist the IP addresses that are able to access the site, and it will appear down for everyone else.
If that's not going to do the trick, you'll probably be best to create your own middleware - it will likely be similar to the CheckForMaintenanceMode middleware that Laravel ships with. In the handle method you can check for the configuration option to see if you're in preview mode or not, and then decide how to handle the request.
If you're using "RESTful" routing like Laravel recommends - that is, GET requests are idempotent and don't change anything, and only POST/PUT/DELETE requests make changes - your middleware can simply return a HTTP 403 response (forbidden) if your preview mode is enabled and the request method isn't GET.
A very simple implementation (you'll likely need to tweak) to get you started would be something like this:
public function handle($request, Closure $next) {
if (config('app.mode') === 'preview' && $request->method() !== 'GET') {
abort(403);
}
return $next($request);
}
Just in regard to using config('app.mode') instead of something env('APP_MODE') is that you shouldn't be using the env helper outside of the configuration files - otherwise you can't take advantage of Laravel's config caching. So add another config option in the config/app.php file that you can use to check the mode the app is in.
I started working on a project which should have admin panel and frontend and I want to use CodeIgniter framework on client request. But the problem is I am not able to understand how to start the project as mentioned above.
I want folder similar to the image shared
Besides the Admin_controller (for separeted security rules), for better organization, it's good to use some extension like this one:
HMVC: https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/src
With this you'll be able to that this type os structure:
URLs
http://awesome.site/public_controller
http://awesome.site/*module_name*/*controller_inside_module*
http://awesome.site/admin/login
Try using Codeigniter's session functionality to authenticate the user and his role (e.g., "admin", "customer", etc)
Then add a constructor like this to every controller (this is just an example)
class Admin_only extends CI_Controller {
public function __construct()
{
parent::__construct();
if( !isset($this->session->userdata['logged_in']) || $this->session->userdata['logged_in']['user_type'] != 'administrator' )
{
// you're not welcome here
redirect('welcome/access_error');
}
}
The __construct() is run every time anything within the controller is accessed.
See how in my example (there's cleaner ways, but this will definitely work), I'm constantly checking if the user is logged in AND if the user is an administrator (actually I'm checking the opposite... logged out OR not administrator, but it's pretty much the same thing logically) and if the check fails, the user is redirected away from the controller.
I am working on a new website being built in SilverStripe. Currently I am having a ton of trouble trying to get the system to let me change the URL alias (or create a second one) for the Security controller's login (and eventually logout) function.
I have tried playing around with the routes.yml file and I tried creating the paths in my own UserController and loading directly from the Security controller with "return Security::login()". But that gives me errors about the use of the static functions.
Unfortunately I don't come from a ton of object oriented experience and this is the first CMS I have used that actually uses a bunch of true object orientation. The current version of SilverStripe we are using is 3.0 (but we will be upgrading to 3.1.1 in a few days).
Does anyone know much about the routing in SilverStripe?
as you stated correctly, SilverStripe has routes, and they can be defined in a yaml config file.
if you take a look at the existing routes.yml in the framework you can see how the default security route is defined:
https://github.com/silverstripe/silverstripe-framework/blob/fd6a1619cb7696d0f7e3ab344bc5ac7d9f6cfe77/_config/routes.yml#L17
if you just want to replace the Secuirty in Secuirty/login, its as easy as just creating your own routes.ymlin mysite/_config/ with the following content:
---
Name: myroutesorsomeotherrandomname
Before: '*'
After:
- '#rootroutes'
- '#coreroutes'
- '#modelascontrollerroutes'
- '#adminroutes'
---
Director:
rules:
'foobar//$Action/$ID/$OtherID': 'Security'
NOTE: make sure you ran a ?flush=1 to ensure the yml file is loaded (they get cached)
also make sure you use spaces in the yml file, if you use tabs you are going to have a bad time
if you however wish to also replace /login and /logout this is no longer a thing for routing.
login and logout are actions (php functions that are listed in Security::$allowed_actions and thus available as URL) on the on Security.
but its still rather easy, just subclass Security and create the actions you want:
<?php
class MySuperSecurity extends Security {
private static $allowed_actions = array(
'showMeTheLoginForm',
'alternative_login_action_with_dashes',
'doTheLogout',
);
function showMeTheLoginForm() {
// can be visited via http://website.com/foobar/showMeTheLoginForm
return $this->login();
}
function alternative_login_action_with_dashes() {
// can be visited via http://website.com/foobar/alternative-login-action-with-dashes
return $this->login();
}
function doTheLogout($redirect = true) {
// can be visited via http://website.com/foobar/doTheLogout
return $this->logout($redirect);
}
}
and make the route point to your new class instead of Security inside the routes.yml:
'foobar//$Action/$ID/$OtherID': 'MySuperSecurity'
NOTE: again, make sure you did a ?flush=1, both the private static $allowed_actions as well as the yml config file are cached by silverstripe.
NOTE: both solutions suggested in this post will create an additional route to login and does not replace the existing one, so the old Security/login will still be available
I don't know nothing about SilverStripe excepting that is a CMS, but i think SilverStripe must provide a way to aliases Url. Also an alternative is create Alias in virtual host definition if you're using apache or in .htaccess file. Refer to apache doc to further details. If you post a skeleton of your .htaccess file or VirtualHost definition i could help you.
I'm using CakePHP 2.1 RC + TinyAuthorize, the next way in AppController.php:
class AppController extends Controller {
public $components = array('Auth');
public function beforeFilter() {
$this->Auth->authorize = array('Tiny');
}
}
For some reason, Tiny doesn't get executed, thereby it's ACL rules not applied. Any ideas what could be wrong?
did you put it in app or tools plugin?
for the latter it is supposed to be
$this->Auth->authorize = array('Tools.Tiny');
see http://www.dereuromark.de/2011/12/18/tinyauth-the-fastest-and-easiest-authorization-for-cake2/ for details
After figuring out your problem I edit my answer:
This * (= any) placeholder for “roles” only refers to those users that are logged in. You must not declare your public actions this way! All those must be declared using $this->Auth->allow().
The reason is that Authenticate comes before Authorize. So without Authentication (logged in) there will never be any Authorization (check on roles).