This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 6512a4804847c522926182830c6c21ac616f1248
Author: Felix Auringer <[email protected]>
AuthorDate: Mon Jul 21 14:39:04 2025 +0200

    feat(managesieve): add XOAUTH2 authentication mechanism
---
 protocols/managesieve/pom.xml                      |   8 ++
 .../managesieve/api/CapabilityAdvertiser.java      |  27 -----
 .../org/apache/james/managesieve/api/Session.java  |   6 ++
 .../managesieve/api/commands/Authenticate.java     |   2 +-
 .../managesieve/api/commands/CoreCommands.java     |   5 +-
 .../james/managesieve/core/CoreProcessor.java      |  25 ++---
 .../core/XOAUTH2AuthenticationProcessor.java       | 110 +++++++++++++++++++++
 .../managesieve/transcode/ArgumentParser.java      |   4 -
 .../transcode/ManageSieveProcessor.java            |   4 +-
 .../james/managesieve/util/SettableSession.java    |  14 +++
 .../netty/ManageSieveChannelUpstreamHandler.java   |   9 +-
 .../managesieveserver/netty/ManageSieveServer.java |  17 +++-
 12 files changed, 178 insertions(+), 53 deletions(-)

diff --git a/protocols/managesieve/pom.xml b/protocols/managesieve/pom.xml
index fb367c75f5..5522b6fa88 100644
--- a/protocols/managesieve/pom.xml
+++ b/protocols/managesieve/pom.xml
@@ -41,11 +41,19 @@
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-data-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-jwt</artifactId>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${james.protocols.groupId}</groupId>
+            <artifactId>protocols-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/CapabilityAdvertiser.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/CapabilityAdvertiser.java
deleted file mode 100644
index de8c12ad10..0000000000
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/CapabilityAdvertiser.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *   Licensed to the Apache Software Foundation (ASF) under one
- *   or more contributor license agreements.  See the NOTICE file
- *   distributed with this work for additional information
- *   regarding copyright ownership.  The ASF licenses this file
- *   to you under the Apache License, Version 2.0 (the
- *   "License"); you may not use this file except in compliance
- *   with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *   Unless required by applicable law or agreed to in writing,
- *   software distributed under the License is distributed on an
- *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *   KIND, either express or implied.  See the License for the
- *   specific language governing permissions and limitations
- *   under the License.
- *
- */
-
-package org.apache.james.managesieve.api;
-
-public interface CapabilityAdvertiser {
-
-    String getAdvertisedCapabilities();
-
-}
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/Session.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/Session.java
index c33293d8ee..ca5ed2b2fa 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/Session.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/Session.java
@@ -20,8 +20,11 @@
 
 package org.apache.james.managesieve.api;
 
+import java.util.Optional;
+
 import org.apache.james.core.Username;
 import org.apache.james.managesieve.api.commands.Authenticate;
+import org.apache.james.protocols.api.OidcSASLConfiguration;
 
 public interface Session {
 
@@ -51,4 +54,7 @@ public interface Session {
 
     boolean isSslEnabled();
 
+    Optional<OidcSASLConfiguration> getOidcSASLConfiguration();
+
+    void setOidcSASLConfiguration(Optional<OidcSASLConfiguration> 
configuration);
 }
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/Authenticate.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/Authenticate.java
index 02c05311d8..6912348283 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/Authenticate.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/Authenticate.java
@@ -30,7 +30,7 @@ import org.apache.james.managesieve.api.UnknownSaslMechanism;
 public interface Authenticate {
 
     enum SupportedMechanism {
-        PLAIN;
+        PLAIN, XOAUTH2;
 
         public static SupportedMechanism retrieveMechanism(String 
serializedData) throws UnknownSaslMechanism {
             for (SupportedMechanism supportedMechanism : 
SupportedMechanism.values()) {
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/CoreCommands.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/CoreCommands.java
index 092472a955..6016b9c192 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/CoreCommands.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/api/commands/CoreCommands.java
@@ -20,15 +20,12 @@
 
 package org.apache.james.managesieve.api.commands;
 
-import org.apache.james.managesieve.api.CapabilityAdvertiser;
-
 /**
  * Core RFC 5804 Commands common to all transports
  * 
  * @see <a href=http://tools.ietf.org/html/rfc5804#section-2>RFC 5804 
Commands</a>
  */
 public interface CoreCommands extends Capability, CheckScript, DeleteScript, 
GetScript, HaveSpace,
-        ListScripts, PutScript, RenameScript, SetActive, Noop, Unauthenticate, 
Logout, Authenticate, StartTLS,
-        CapabilityAdvertiser {
+        ListScripts, PutScript, RenameScript, SetActive, Noop, Unauthenticate, 
Logout, Authenticate, StartTLS {
 
 }
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
index c4bbe10691..c8f6aab73b 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/CoreProcessor.java
@@ -22,7 +22,6 @@ package org.apache.james.managesieve.core;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -57,7 +56,6 @@ import org.apache.james.user.api.UsersRepository;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 public class CoreProcessor implements CoreCommands {
@@ -83,11 +81,6 @@ public class CoreProcessor implements CoreCommands {
         this.authenticationProcessorMap.put(SupportedMechanism.PLAIN, new 
PlainAuthenticationProcessor(usersRepository));
     }
 
-    @Override
-    public String getAdvertisedCapabilities() {
-        return convertCapabilityMapToString(capabilitiesBase) + "\r\n";
-    }
-
     @Override
     public String capability(Session session) {
         return convertCapabilityMapToString(computeCapabilityMap(session)) + 
"\r\nOK";
@@ -106,6 +99,10 @@ public class CoreProcessor implements CoreCommands {
         if (session.isAuthenticated()) {
             capabilities.put(Capabilities.OWNER, session.getUser().asString());
         }
+        session.getOidcSASLConfiguration().ifPresent(oidcConfiguration -> {
+            
this.authenticationProcessorMap.putIfAbsent(SupportedMechanism.XOAUTH2, new 
XOAUTH2AuthenticationProcessor(oidcConfiguration));
+        });
+        capabilities.put(Capabilities.SASL, 
constructSaslSupportedAuthenticationMechanisms());
         return capabilities;
     }
 
@@ -218,6 +215,9 @@ public class CoreProcessor implements CoreCommands {
             }
             String unquotedMechanism = ParserUtils.unquoteFirst(mechanism);
             SupportedMechanism supportedMechanism = 
SupportedMechanism.retrieveMechanism(unquotedMechanism);
+            if 
(!this.authenticationProcessorMap.containsKey(supportedMechanism)) {
+                throw new UnknownSaslMechanism("SASL mechanism disabled: " + 
unquotedMechanism);
+            }
 
             session.setChoosedAuthenticationMechanism(supportedMechanism);
             session.setState(Session.State.AUTHENTICATION_IN_PROGRESS);
@@ -328,7 +328,6 @@ public class CoreProcessor implements CoreCommands {
         Map<Capabilities, String> capabilitiesBase = new HashMap<>();
         capabilitiesBase.put(Capabilities.IMPLEMENTATION, 
IMPLEMENTATION_DESCRIPTION);
         capabilitiesBase.put(Capabilities.VERSION, MANAGE_SIEVE_VERSION);
-        capabilitiesBase.put(Capabilities.SASL, 
constructSaslSupportedAuthenticationMechanisms());
         capabilitiesBase.put(Capabilities.STARTTLS, null);
         if (!extensions.isEmpty()) {
             capabilitiesBase.put(Capabilities.SIEVE, extensions);
@@ -337,10 +336,12 @@ public class CoreProcessor implements CoreCommands {
     }
 
     private String constructSaslSupportedAuthenticationMechanisms() {
-        return Joiner.on(' ')
-            .join(Lists.transform(
-                Arrays.asList(SupportedMechanism.values()),
-                Enum::toString));
+        return Joiner.on(' ').join(this.authenticationProcessorMap
+            .keySet()
+            .stream()
+            .map(Enum::toString)
+            .iterator()
+        );
     }
 
     private String sanitizeString(String message) {
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/XOAUTH2AuthenticationProcessor.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/XOAUTH2AuthenticationProcessor.java
new file mode 100644
index 0000000000..8a65202ac5
--- /dev/null
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/core/XOAUTH2AuthenticationProcessor.java
@@ -0,0 +1,110 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.james.managesieve.core;
+
+import java.util.Optional;
+
+import org.apache.james.core.Username;
+import org.apache.james.jwt.OidcJwtTokenVerifier;
+import org.apache.james.jwt.introspection.IntrospectionEndpoint;
+import org.apache.james.managesieve.api.AuthenticationException;
+import org.apache.james.managesieve.api.AuthenticationProcessor;
+import org.apache.james.managesieve.api.Session;
+import org.apache.james.managesieve.api.SyntaxException;
+import org.apache.james.protocols.api.OIDCSASLParser;
+import org.apache.james.protocols.api.OIDCSASLParser.OIDCInitialResponse;
+import org.apache.james.protocols.api.OidcSASLConfiguration;
+
+import reactor.core.publisher.Mono;
+
+public class XOAUTH2AuthenticationProcessor implements AuthenticationProcessor 
{
+
+    private final OidcSASLConfiguration oidcConfiguration;
+
+    public XOAUTH2AuthenticationProcessor(OidcSASLConfiguration 
oidcConfiguration) {
+        this.oidcConfiguration = oidcConfiguration;
+    }
+
+    @Override
+    public String initialServerResponse(Session session) {
+        return "+ \"\"";
+    }
+
+    @Override
+    public Username isAuthenticationSuccesfull(Session session, String 
suppliedClientData) throws SyntaxException, AuthenticationException {
+        Optional<OIDCInitialResponse> oidcInitialResponseResult = 
OIDCSASLParser.parse(suppliedClientData);
+        if (oidcInitialResponseResult.isEmpty()) {
+            throw new SyntaxException("Could not parse the given JWT");
+        }
+        OIDCInitialResponse oidcInitialResponse = 
oidcInitialResponseResult.get();
+
+        Optional<Username> authenticatedUserResult = Optional.empty();
+        try {
+            authenticatedUserResult = 
validateToken(oidcInitialResponse.getToken());
+        } catch (Exception e) {
+            throw new AuthenticationException("Could not validate the JWT");
+        }
+        if (authenticatedUserResult.isEmpty()) {
+            throw new AuthenticationException("Could not validate the JWT");
+        }
+        Username authenticatedUser = authenticatedUserResult.get();
+
+        // The user from the managesieve AUTHENTICATE command must match the 
username in the token.
+        Username associatedUser = 
Username.of(oidcInitialResponse.getAssociatedUser());
+        if (!authenticatedUser.equals(associatedUser)) {
+            throw new AuthenticationException("Mismatch between user from 
command and JWT");
+        }
+
+        return authenticatedUser;
+    }
+
+    private Optional<Username> validateToken(String token) {
+        if (this.oidcConfiguration.isCheckTokenByIntrospectionEndpoint()) {
+            return validTokenWithIntrospection(token);
+        } else if (this.oidcConfiguration.isCheckTokenByUserinfoEndpoint()) {
+            return validTokenWithUserInfo(token);
+        } else {
+            return OidcJwtTokenVerifier.verifySignatureAndExtractClaim(token, 
this.oidcConfiguration.getJwksURL(), this.oidcConfiguration.getClaim())
+                .map(Username::of);
+        }
+    }
+
+    private Optional<Username> validTokenWithUserInfo(String token) {
+        return Mono.from(OidcJwtTokenVerifier.verifyWithUserinfo(token,
+                this.oidcConfiguration.getJwksURL(),
+                this.oidcConfiguration.getClaim(),
+                this.oidcConfiguration.getUserInfoEndpoint().orElseThrow()))
+            .blockOptional()
+            .map(Username::of);
+    }
+
+    private Optional<Username> validTokenWithIntrospection(String token) {
+        return Mono.from(OidcJwtTokenVerifier.verifyWithIntrospection(token,
+                this.oidcConfiguration.getJwksURL(),
+                this.oidcConfiguration.getClaim(),
+                this.oidcConfiguration.getIntrospectionEndpoint()
+                    .map(endpoint -> new IntrospectionEndpoint(endpoint, 
this.oidcConfiguration.getIntrospectionEndpointAuthorization()))
+                    .orElseThrow()))
+            .blockOptional()
+            .map(Username::of);
+    }
+}
+
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ArgumentParser.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ArgumentParser.java
index e9f78f2629..c6d2cb16f6 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ArgumentParser.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ArgumentParser.java
@@ -53,10 +53,6 @@ public class ArgumentParser {
         this.validatePutSize = validatePutSize;
     }
 
-    public String getAdvertisedCapabilities() {
-        return core.getAdvertisedCapabilities();
-    }
-
     public String capability(Session session, String args) {
         if (!args.trim().isEmpty()) {
             return "NO \"Too many arguments: " + args + "\"";
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ManageSieveProcessor.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ManageSieveProcessor.java
index a68359ce8f..94708c1761 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ManageSieveProcessor.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/transcode/ManageSieveProcessor.java
@@ -129,8 +129,8 @@ public class ManageSieveProcessor {
         return "NO unknown " + command + " command";
     }
 
-    public String getAdvertisedCapabilities() {
-        return argumentParser.getAdvertisedCapabilities();
+    public String getAdvertisedCapabilities(Session session) {
+        return argumentParser.capability(session, "") + "\r\n";
     }
 
 }
diff --git 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/util/SettableSession.java
 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/util/SettableSession.java
index 09b49dea6e..f689ffcc2e 100644
--- 
a/protocols/managesieve/src/main/java/org/apache/james/managesieve/util/SettableSession.java
+++ 
b/protocols/managesieve/src/main/java/org/apache/james/managesieve/util/SettableSession.java
@@ -20,9 +20,12 @@
 
 package org.apache.james.managesieve.util;
 
+import java.util.Optional;
+
 import org.apache.james.core.Username;
 import org.apache.james.managesieve.api.Session;
 import org.apache.james.managesieve.api.commands.Authenticate;
+import org.apache.james.protocols.api.OidcSASLConfiguration;
 
 public class SettableSession implements Session {
 
@@ -30,6 +33,7 @@ public class SettableSession implements Session {
     private State state;
     private Authenticate.SupportedMechanism choosedAuthenticationMechanism;
     private boolean sslEnabled;
+    private Optional<OidcSASLConfiguration> oidcSASLConfiguration = 
Optional.empty();
 
     public SettableSession() {
         this.state = State.UNAUTHENTICATED;
@@ -80,4 +84,14 @@ public class SettableSession implements Session {
     public boolean isSslEnabled() {
         return sslEnabled;
     }
+
+    @Override
+    public Optional<OidcSASLConfiguration> getOidcSASLConfiguration() {
+        return this.oidcSASLConfiguration;
+    }
+
+    @Override
+    public void setOidcSASLConfiguration(Optional<OidcSASLConfiguration> 
configuration) {
+        this.oidcSASLConfiguration = configuration;
+    }
 }
diff --git 
a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
 
b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
index 444d426351..0e6454ad80 100644
--- 
a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
+++ 
b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveChannelUpstreamHandler.java
@@ -21,12 +21,14 @@ package org.apache.james.managesieveserver.netty;
 
 import java.io.Closeable;
 import java.net.InetSocketAddress;
+import java.util.Optional;
 
 import org.apache.james.managesieve.api.Session;
 import org.apache.james.managesieve.api.SessionTerminatedException;
 import org.apache.james.managesieve.transcode.ManageSieveProcessor;
 import org.apache.james.managesieve.transcode.NotEnoughDataException;
 import org.apache.james.managesieve.util.SettableSession;
+import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.api.ProxyInformation;
 import org.apache.james.protocols.netty.Encryption;
 import org.slf4j.Logger;
@@ -51,12 +53,14 @@ public class ManageSieveChannelUpstreamHandler extends 
ChannelInboundHandlerAdap
     private final ManageSieveProcessor manageSieveProcessor;
     private final Encryption secure;
     private final int maxLineLength;
+    private final Optional<OidcSASLConfiguration> oidcConfiguration;
 
     public ManageSieveChannelUpstreamHandler(
-        ManageSieveProcessor manageSieveProcessor, Encryption secure, int 
maxLineLength) {
+        ManageSieveProcessor manageSieveProcessor, Encryption secure, int 
maxLineLength, Optional<OidcSASLConfiguration> oidcConfiguration) {
         this.manageSieveProcessor = manageSieveProcessor;
         this.secure = secure;
         this.maxLineLength = maxLineLength;
+        this.oidcConfiguration = oidcConfiguration;
     }
 
     private boolean isSSL() {
@@ -146,13 +150,14 @@ public class ManageSieveChannelUpstreamHandler extends 
ChannelInboundHandlerAdap
             LOGGER.info("Connection established from {}", 
address.getAddress().getHostAddress());
 
             Session session = new SettableSession();
+            session.setOidcSASLConfiguration(this.oidcConfiguration);
             if (isSSL()) {
                 session.setSslEnabled(true);
             }
             
ctx.channel().attr(NettyConstants.SESSION_ATTRIBUTE_KEY).set(session);
             
ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).set(new 
ChannelManageSieveResponseWriter(ctx.channel()));
             super.channelActive(ctx);
-            
ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).get().write(manageSieveProcessor.getAdvertisedCapabilities()
 + "OK\r\n");
+            
ctx.channel().attr(NettyConstants.RESPONSE_WRITER_ATTRIBUTE_KEY).get().write(manageSieveProcessor.getAdvertisedCapabilities(session));
         }
     }
 
diff --git 
a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
 
b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
index 114b082217..3c52a0f6c7 100644
--- 
a/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
+++ 
b/server/protocols/protocols-managesieve/src/main/java/org/apache/james/managesieveserver/netty/ManageSieveServer.java
@@ -19,12 +19,15 @@
 
 package org.apache.james.managesieveserver.netty;
 
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.util.Optional;
 
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.apache.james.managesieve.transcode.ManageSieveProcessor;
+import org.apache.james.protocols.api.OidcSASLConfiguration;
 import org.apache.james.protocols.lib.netty.AbstractConfigurableAsyncServer;
 import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import 
org.apache.james.protocols.netty.AllButStartTlsLineChannelHandlerFactory;
@@ -48,11 +51,13 @@ import io.netty.util.CharsetUtil;
 public class ManageSieveServer extends AbstractConfigurableAsyncServer 
implements ManageSieveServerMBean {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(ManageSieveServer.class);
+    static final String OIDC_PATH = "oidc";
 
     private final int maxLineLength;
     private final ManageSieveProcessor manageSieveProcessor;
     private Optional<ConnectionLimitUpstreamHandler> 
connectionLimitUpstreamHandler = Optional.empty();
     private Optional<ConnectionPerIpLimitUpstreamHandler> 
connectionPerIpLimitUpstreamHandler = Optional.empty();
+    private Optional<OidcSASLConfiguration> oidcConfiguration;
 
     public ManageSieveServer(int maxLineLength, ManageSieveProcessor 
manageSieveProcessor) {
         this.maxLineLength = maxLineLength;
@@ -70,6 +75,16 @@ public class ManageSieveServer extends 
AbstractConfigurableAsyncServer implement
 
         connectionLimitUpstreamHandler = 
ConnectionLimitUpstreamHandler.forCount(connectionLimit);
         connectionPerIpLimitUpstreamHandler = 
ConnectionPerIpLimitUpstreamHandler.forCount(connPerIP);
+
+        if (config.immutableChildConfigurationsAt(OIDC_PATH).isEmpty()) {
+            this.oidcConfiguration = Optional.empty();
+        } else {
+            try {
+                this.oidcConfiguration = 
Optional.of(OidcSASLConfiguration.parse(config.configurationAt(OIDC_PATH)));
+            } catch (MalformedURLException | NullPointerException | 
URISyntaxException exception) {
+                throw new ConfigurationException("Failed to parse OIDC 
configuration", exception);
+            }
+        }
     }
 
     @Override
@@ -79,7 +94,7 @@ public class ManageSieveServer extends 
AbstractConfigurableAsyncServer implement
 
     @Override
     protected ChannelInboundHandlerAdapter createCoreHandler() {
-        return new ManageSieveChannelUpstreamHandler(manageSieveProcessor, 
getEncryption(), maxLineLength);
+        return new ManageSieveChannelUpstreamHandler(manageSieveProcessor, 
getEncryption(), maxLineLength, this.oidcConfiguration);
     }
 
     @Override


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to