diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebAuthInfo.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebAuthInfo.java index 67eb0e9196..06663c190d 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebAuthInfo.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebAuthInfo.java @@ -17,7 +17,6 @@ package io.cloudbeaver.model.session; import io.cloudbeaver.DBWUserIdentity; -import io.cloudbeaver.model.WebAsyncTaskInfo; import io.cloudbeaver.model.user.WebAuthProviderConfiguration; import io.cloudbeaver.model.user.WebUser; import io.cloudbeaver.model.user.WebUserOriginInfo; @@ -47,8 +46,6 @@ public class WebAuthInfo implements SMSessionPrincipal { private final OffsetDateTime loginTime; private final DBWUserIdentity userIdentity; private String message; - private String redirectLink; - private final WebAsyncTaskInfo taskInfo; private transient Map userCredentials; @@ -65,22 +62,6 @@ public class WebAuthInfo implements SMSessionPrincipal { this.userIdentity = userIdentity; this.authSession = authSession; this.loginTime = loginTime; - this.taskInfo = null; - } - - public WebAuthInfo(@NotNull WebSession session, - @NotNull WebAsyncTaskInfo taskInfo, - @NotNull String redirectLink - ) { - this.session = session; - this.taskInfo = taskInfo; - this.redirectLink = redirectLink; - - this.user = null; - this.authProvider = null; - this.userIdentity = null; - this.authSession = null; - this.loginTime = null; } @Property diff --git a/server/bundles/io.cloudbeaver.service.auth/schema/service.auth.graphqls b/server/bundles/io.cloudbeaver.service.auth/schema/service.auth.graphqls index 35a018f087..65b261e021 100644 --- a/server/bundles/io.cloudbeaver.service.auth/schema/service.auth.graphqls +++ b/server/bundles/io.cloudbeaver.service.auth/schema/service.auth.graphqls @@ -62,6 +62,14 @@ type AuthProviderInfo { requiredFeatures: [String!]! } +type AuthInfo { + redirectLink: String + + taskInfo: AsyncTaskInfo + + userTokens: [UserAuthToken!] +} + type UserAuthToken { # Auth provider used for authorization authProvider: ID! @@ -70,23 +78,20 @@ type UserAuthToken { authConfiguration: ID # Authorization time - loginTime: DateTime + loginTime: DateTime! # User identity (aka user name) specific to auth provider - userId: String + userId: String! # User display name specific to auth provider - displayName: String + displayName: String! # Optional login message message: String # Auth origin - origin: ObjectOrigin + origin: ObjectOrigin! - redirectLink: String - - taskInfo: AsyncTaskInfo } type UserInfo { @@ -110,7 +115,10 @@ type UserInfo { extend type Query { # Authorize user using specified auth provider. If linkUser=true then associates new - authLogin(provider: ID!, configuration: ID, credentials: Object!, linkUser: Boolean): UserAuthToken! + authLogin(provider: ID!, configuration: ID, credentials: Object!, linkUser: Boolean): AuthInfo! + + #User tokens from authorization task, null if task not finished or finished with error + authTaskResults(taskId: ID!):[UserAuthToken!] # Logouts user. If provider not specified then all authorizations are revoked from session. authLogout(provider: ID, configuration: ID): Boolean diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/DBWServiceAuth.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/DBWServiceAuth.java index 4738728f54..7681fb5a21 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/DBWServiceAuth.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/DBWServiceAuth.java @@ -33,15 +33,18 @@ import java.util.Map; */ public interface DBWServiceAuth extends DBWService { - @WebAction(requirePermissions = {} ) - WebAuthInfo authLogin( + @WebAction(requirePermissions = {}) + WebAuthStatus authLogin( @NotNull WebSession webSession, @NotNull String providerId, @Nullable String providerConfigurationId, @NotNull Map credentials, boolean linkWithActiveUser) throws DBWebException; - @WebAction(requirePermissions = {} ) + @WebAction(requirePermissions = {}) + WebAuthInfo[] getAuthTaskResult(@NotNull WebSession webSession, @NotNull String taskId) throws DBWebException; + + @WebAction(requirePermissions = {}) void authLogout(@NotNull WebSession webSession, @Nullable String providerId) throws DBWebException; @WebAction(requirePermissions = {}) diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebAuthStatus.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebAuthStatus.java new file mode 100644 index 0000000000..0e696799aa --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebAuthStatus.java @@ -0,0 +1,40 @@ +package io.cloudbeaver.service.auth; + +import io.cloudbeaver.model.WebAsyncTaskInfo; +import io.cloudbeaver.model.session.WebAuthInfo; +import org.jkiss.dbeaver.model.meta.Property; + +import java.util.List; + +public class WebAuthStatus { + private final WebAsyncTaskInfo taskInfo; + private final String redirectUrl; + private final List userTokens; + + public WebAuthStatus(WebAsyncTaskInfo taskInfo, String redirectUrl) { + this.taskInfo = taskInfo; + this.redirectUrl = redirectUrl; + this.userTokens = null; + } + + public WebAuthStatus(List userTokens) { + this.taskInfo = null; + this.redirectUrl = null; + this.userTokens = userTokens; + } + + @Property + public WebAsyncTaskInfo getTaskInfo() { + return taskInfo; + } + + @Property + public String getRedirectUrl() { + return redirectUrl; + } + + @Property + public List getUserTokens() { + return userTokens; + } +} diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebServiceBindingAuth.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebServiceBindingAuth.java index 66ff2dffea..c1cd218e44 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebServiceBindingAuth.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/WebServiceBindingAuth.java @@ -46,6 +46,7 @@ public class WebServiceBindingAuth extends WebServiceBindingBase getService(env).authLogout(getWebSession(env), env.getArgument("provider")); return true; }) + .dataFetcher("authTaskResults", env -> getService(env).getAuthTaskResult(getWebSession(env), env.getArgument("taskId"))) .dataFetcher("activeUser", env -> getService(env).activeUser(getWebSession(env, false))) .dataFetcher("authProviders", env -> getService(env).getAuthProviders()) .dataFetcher("authChangeLocalPassword", env -> getService(env).changeLocalPassword( diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java index 71c04fe772..8c272899a7 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java @@ -28,6 +28,7 @@ import io.cloudbeaver.model.user.WebUser; import io.cloudbeaver.registry.WebUserProfileRegistry; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.service.auth.DBWServiceAuth; +import io.cloudbeaver.service.auth.WebAuthStatus; import io.cloudbeaver.service.auth.WebUserInfo; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; @@ -51,7 +52,7 @@ public class WebServiceAuthImpl implements DBWServiceAuth { public static final String CONFIG_TEMP_ADMIN_USER_ID = "temp_config_admin"; @Override - public WebAuthInfo authLogin( + public WebAuthStatus authLogin( @NotNull WebSession webSession, @NotNull String providerId, @Nullable String providerConfigurationId, @@ -76,13 +77,12 @@ public class WebServiceAuthImpl implements DBWServiceAuth { if (smAuthInfo.getAuthStatus() == SMAuthStatus.IN_PROGRESS) { //run async auth process WebAsyncTaskInfo taskInfo = webSession.createAndRunAsyncTask("Authentication", new WebSessionAuthJob(webSession, smAuthInfo, linkWithActiveUser)); - return new WebAuthInfo(webSession, taskInfo, smAuthInfo.getRedirectUrl()); + return new WebAuthStatus(taskInfo, smAuthInfo.getRedirectUrl()); } else { //run it sync var job = new WebSessionAuthJob(webSession, smAuthInfo, linkWithActiveUser); job.run(webSession.getProgressMonitor()); - //TODO return list - return ((List) job.getExtendedResults()).stream().findFirst().orElseThrow(); + return new WebAuthStatus(((List) job.getExtendedResults())); } } catch (Exception e) { throw new DBWebException("User authentication failed", e); @@ -90,6 +90,16 @@ public class WebServiceAuthImpl implements DBWServiceAuth { } + @Override + public WebAuthInfo[] getAuthTaskResult(@NotNull WebSession webSession, @NotNull String taskId) throws DBWebException { + WebAsyncTaskInfo taskInfo = webSession.asyncTaskStatus(taskId, true); + List result = (List) taskInfo.getExtendedResult(); + if (result == null) { + return null; + } + return result.toArray(WebAuthInfo[]::new); + } + @Override public void authLogout(@NotNull WebSession webSession, @Nullable String providerId) throws DBWebException { if (webSession.getUser() == null) {