public void run() {
    final ArrayList<LoginEvent> events = new ArrayList<LoginEvent>(TRANSACTION_SIZE + 1);
    while (run) {
      try {
        LoginEvent take = queue.poll(2, TimeUnit.SECONDS);
        if (take == null) {
          continue;
        }
        try {
          events.add(take);
          queue.drainTo(events, TRANSACTION_SIZE);
          for (LoginEvent event : events) {
            if (event instanceof FailedLogin) {
              logFailure(event);
            } else {
              logSuccess(event);
            }
          }

          Collections.sort(
              events); // we sort to avoid deadlock due to ordered updates.  Maybe I'm overthinking
          // this.
          KeycloakSession session = factory.createSession();
          try {
            for (LoginEvent event : events) {
              if (event instanceof FailedLogin) {
                failure(session, event);
              }
            }
            session.getTransaction().commit();
          } catch (Exception e) {
            session.getTransaction().rollback();
            throw e;
          } finally {
            for (LoginEvent event : events) {
              if (event instanceof FailedLogin) {
                ((FailedLogin) event).latch.countDown();
              }
            }
            events.clear();
            session.close();
          }
        } catch (Exception e) {
          logger.error("Failed processing event", e);
        }
      } catch (InterruptedException e) {
        break;
      } finally {
        shutdownLatch.countDown();
      }
    }
  }
Example #2
0
  public void transformIDToken(
      KeycloakSession session,
      IDToken token,
      RealmModel realm,
      ClientModel client,
      UserModel user,
      UserSessionModel userSession,
      ClientSessionModel clientSession) {
    Set<ProtocolMapperModel> mappings =
        new ClientSessionCode(realm, clientSession).getRequestedProtocolMappers();
    KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
    for (ProtocolMapperModel mapping : mappings) {

      ProtocolMapper mapper =
          (ProtocolMapper)
              sessionFactory.getProviderFactory(ProtocolMapper.class, mapping.getProtocolMapper());
      if (mapper == null || !(mapper instanceof OIDCIDTokenMapper)) continue;
      token =
          ((OIDCIDTokenMapper) mapper)
              .transformIDToken(token, mapping, session, userSession, clientSession);
    }
  }
  @Override
  public void postInit(KeycloakSessionFactory factory) {
    factory.register(
        event -> {
          if (event instanceof ClientRemovedEvent) {
            KeycloakSession keycloakSession = ((ClientRemovedEvent) event).getKeycloakSession();
            AuthorizationProvider provider =
                keycloakSession.getProvider(AuthorizationProvider.class);
            PolicyStore policyStore = provider.getStoreFactory().getPolicyStore();
            ClientModel removedClient = ((ClientRemovedEvent) event).getClient();

            policyStore
                .findByType(getId())
                .forEach(
                    policy -> {
                      List<String> clients = new ArrayList<>();

                      for (String clientId : getClients(policy)) {
                        if (!clientId.equals(removedClient.getId())) {
                          clients.add(clientId);
                        }
                      }

                      try {
                        if (clients.isEmpty()) {
                          policyStore
                              .findDependentPolicies(policy.getId())
                              .forEach(
                                  dependentPolicy -> {
                                    dependentPolicy.removeAssociatedPolicy(policy);
                                  });
                          policyStore.delete(policy.getId());
                        } else {
                          policy
                              .getConfig()
                              .put("clients", JsonSerialization.writeValueAsString(clients));
                        }
                      } catch (IOException e) {
                        throw new RuntimeException(
                            "Error while synchronizing clients with policy ["
                                + policy.getName()
                                + "].",
                            e);
                      }
                    });
          }
        });
  }
  @Override
  public void postInit(final KeycloakSessionFactory factory) {
    // Max count of worker errors. Initialization will end with exception when this number is
    // reached
    final int maxErrors = config.getInt("maxErrors", 20);

    // Count of sessions to be computed in each segment
    final int sessionsPerSegment = config.getInt("sessionsPerSegment", 100);

    factory.register(
        new ProviderEventListener() {

          @Override
          public void onEvent(ProviderEvent event) {
            if (event instanceof PostMigrationEvent) {
              loadPersistentSessions(factory, maxErrors, sessionsPerSegment);
            }
          }
        });
  }