1919use OCA \UserOIDC \Listener \ExternalTokenRequestedListener ;
2020use OCA \UserOIDC \Listener \InternalTokenRequestedListener ;
2121use OCA \UserOIDC \Listener \TimezoneHandlingListener ;
22+ use OCA \UserOIDC \MagentaBearer \MBackend ;
2223use OCA \UserOIDC \Listener \TokenInvalidatedListener ;
2324use OCA \UserOIDC \Service \ID4MeService ;
25+ use OCA \UserOIDC \Service \ProvisioningEventService ;
26+ use OCA \UserOIDC \Service \ProvisioningService ;
2427use OCA \UserOIDC \Service \SettingsService ;
25- use OCA \UserOIDC \Service \TokenService ;
26- use OCA \UserOIDC \User \Backend ;
2728use OCP \AppFramework \App ;
2829use OCP \AppFramework \Bootstrap \IBootContext ;
2930use OCP \AppFramework \Bootstrap \IBootstrap ;
3031use OCP \AppFramework \Bootstrap \IRegistrationContext ;
3132use OCP \IConfig ;
3233use OCP \IL10N ;
3334use OCP \IRequest ;
35+ use OCP \ISession ;
3436use OCP \IURLGenerator ;
3537use OCP \IUserManager ;
3638use OCP \IUserSession ;
39+ use OCP \Security \ISecureRandom ;
40+
41+ // this is needed only for the special, shortened client login flow
42+ use Psr \Container \ContainerInterface ;
3743use Throwable ;
3844
3945class Application extends App implements IBootstrap {
@@ -48,11 +54,19 @@ public function __construct(array $urlParams = []) {
4854 }
4955
5056 public function register (IRegistrationContext $ context ): void {
57+ // Register the composer autoloader required for the added jwt-token libs
58+ include_once __DIR__ . '/../../vendor/autoload.php ' ;
59+
60+ // override registration of provisioning srevice to use event-based solution
61+ $ this ->getContainer ()->registerService (ProvisioningService::class, function (ContainerInterface $ c ): ProvisioningService {
62+ return $ c ->get (ProvisioningEventService::class);
63+ });
64+
5165 /** @var IUserManager $userManager */
5266 $ userManager = $ this ->getContainer ()->get (IUserManager::class);
5367
5468 /* Register our own user backend */
55- $ this ->backend = $ this ->getContainer ()->get (Backend ::class);
69+ $ this ->backend = $ this ->getContainer ()->get (MBackend ::class);
5670
5771 $ config = $ this ->getContainer ()->get (IConfig::class);
5872 if (version_compare ($ config ->getSystemValueString ('version ' , '0.0.0 ' ), '32.0.0 ' , '>= ' )) {
@@ -84,12 +98,69 @@ public function boot(IBootContext $context): void {
8498 try {
8599 $ context ->injectFn (\Closure::fromCallable ([$ this , 'registerRedirect ' ]));
86100 $ context ->injectFn (\Closure::fromCallable ([$ this , 'registerLogin ' ]));
101+ // this is the custom auto-redirect for MagentaCLOUD client access
102+ $ context ->injectFn (\Closure::fromCallable ([$ this , 'registerNmcClientFlow ' ]));
87103 } catch (Throwable $ e ) {
88104 }
89105 }
90106
91- private function checkLoginToken (TokenService $ tokenService ): void {
92- $ tokenService ->checkLoginToken ();
107+ /**
108+ * This is the automatic redirect exclusively for Nextcloud/Magentacloud clients completely skipping consent layer
109+ */
110+ private function registerNmcClientFlow (IRequest $ request ,
111+ IURLGenerator $ urlGenerator ,
112+ ProviderMapper $ providerMapper ,
113+ ISession $ session ,
114+ ISecureRandom $ random ): void {
115+ $ providers = $ this ->getCachedProviders ($ providerMapper );
116+
117+ // Handle immediate redirect on client first-time login
118+ $ isClientLoginFlow = false ;
119+
120+ try {
121+ $ isClientLoginFlow = $ request ->getPathInfo () === '/login/flow ' ;
122+ } catch (Exception $ e ) {
123+ // in case any errors happen when checking for the path do not apply redirect logic as it is only needed for the login
124+ }
125+
126+ if ($ isClientLoginFlow ) {
127+ // only redirect if Telekom provider registered
128+ $ tproviders = array_values (array_filter ($ providers , function ($ p ) {
129+ return strtolower ($ p ->getIdentifier ()) === 'telekom ' ;
130+ }));
131+
132+ if (count ($ tproviders ) == 0 ) {
133+ // always show normal login flow as error fallback
134+ return ;
135+ }
136+
137+ $ stateToken = $ random ->generate (64 , ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS );
138+ $ session ->set ('client.flow.state.token ' , $ stateToken );
139+
140+ // call the service to get the params, but suppress the template
141+ // compute grant redirect Url to go directly to Telekom login
142+ $ redirectUrl = $ urlGenerator ->linkToRoute ('core.ClientFlowLogin.grantPage ' , [
143+ 'stateToken ' => $ stateToken ,
144+ // grantPage service operation is deriving oauth2 client name (again),
145+ // so we simply pass on clientIdentifier or empty string
146+ 'clientIdentifier ' => $ request ->getParam ('clientIdentifier ' , '' ),
147+ 'direct ' => $ request ->getParam ('direct ' , '0 ' )
148+ ]);
149+
150+ if ($ redirectUrl === null ) {
151+ // always show normal login flow as error fallback
152+ return ;
153+ }
154+
155+ // direct login, consent layer later
156+ $ targetUrl = $ urlGenerator ->linkToRoute (self ::APP_ID . '.login.login ' , [
157+ 'providerId ' => $ tproviders [0 ]->getId (),
158+ 'redirectUrl ' => $ redirectUrl
159+ ]);
160+
161+ header ('Location: ' . $ targetUrl );
162+ exit ();
163+ }
93164 }
94165
95166 private function registerRedirect (IRequest $ request , IURLGenerator $ urlGenerator , SettingsService $ settings , ProviderMapper $ providerMapper ): void {
0 commit comments