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 ' , '>= ' )) {
@@ -83,12 +97,69 @@ public function boot(IBootContext $context): void {
8397 try {
8498 $ context ->injectFn (\Closure::fromCallable ([$ this , 'registerRedirect ' ]));
8599 $ context ->injectFn (\Closure::fromCallable ([$ this , 'registerLogin ' ]));
100+ // this is the custom auto-redirect for MagentaCLOUD client access
101+ $ context ->injectFn (\Closure::fromCallable ([$ this , 'registerNmcClientFlow ' ]));
86102 } catch (Throwable $ e ) {
87103 }
88104 }
89105
90- private function checkLoginToken (TokenService $ tokenService ): void {
91- $ tokenService ->checkLoginToken ();
106+ /**
107+ * This is the automatic redirect exclusively for Nextcloud/Magentacloud clients completely skipping consent layer
108+ */
109+ private function registerNmcClientFlow (IRequest $ request ,
110+ IURLGenerator $ urlGenerator ,
111+ ProviderMapper $ providerMapper ,
112+ ISession $ session ,
113+ ISecureRandom $ random ): void {
114+ $ providers = $ this ->getCachedProviders ($ providerMapper );
115+
116+ // Handle immediate redirect on client first-time login
117+ $ isClientLoginFlow = false ;
118+
119+ try {
120+ $ isClientLoginFlow = $ request ->getPathInfo () === '/login/flow ' ;
121+ } catch (Exception $ e ) {
122+ // in case any errors happen when checking for the path do not apply redirect logic as it is only needed for the login
123+ }
124+
125+ if ($ isClientLoginFlow ) {
126+ // only redirect if Telekom provider registered
127+ $ tproviders = array_values (array_filter ($ providers , function ($ p ) {
128+ return strtolower ($ p ->getIdentifier ()) === 'telekom ' ;
129+ }));
130+
131+ if (count ($ tproviders ) == 0 ) {
132+ // always show normal login flow as error fallback
133+ return ;
134+ }
135+
136+ $ stateToken = $ random ->generate (64 , ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS );
137+ $ session ->set ('client.flow.state.token ' , $ stateToken );
138+
139+ // call the service to get the params, but suppress the template
140+ // compute grant redirect Url to go directly to Telekom login
141+ $ redirectUrl = $ urlGenerator ->linkToRoute ('core.ClientFlowLogin.grantPage ' , [
142+ 'stateToken ' => $ stateToken ,
143+ // grantPage service operation is deriving oauth2 client name (again),
144+ // so we simply pass on clientIdentifier or empty string
145+ 'clientIdentifier ' => $ request ->getParam ('clientIdentifier ' , '' ),
146+ 'direct ' => $ request ->getParam ('direct ' , '0 ' )
147+ ]);
148+
149+ if ($ redirectUrl === null ) {
150+ // always show normal login flow as error fallback
151+ return ;
152+ }
153+
154+ // direct login, consent layer later
155+ $ targetUrl = $ urlGenerator ->linkToRoute (self ::APP_ID . '.login.login ' , [
156+ 'providerId ' => $ tproviders [0 ]->getId (),
157+ 'redirectUrl ' => $ redirectUrl
158+ ]);
159+
160+ header ('Location: ' . $ targetUrl );
161+ exit ();
162+ }
92163 }
93164
94165 private function registerRedirect (IRequest $ request , IURLGenerator $ urlGenerator , SettingsService $ settings , ProviderMapper $ providerMapper ): void {
0 commit comments