org.entcore.auth.services.impl.AbstractSSOProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.entcore.auth.services.impl.AbstractSSOProvider.java

Source

/*
 * Copyright  "Open Digital Education", 2015
 *
 * This program is published by "Open Digital Education".
 * You must indicate the name of the software and the company in any production /contribution
 * using the software and indicate on the home page of the software industry in question,
 * "powered by Open Digital Education" with a reference to the website: https://opendigitaleducation.com/.
 *
 * This program is free software, licensed under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation, version 3 of the License.
 *
 * You can redistribute this application and/or modify it since you respect the terms of the GNU Affero General Public License.
 * If you modify the source code and then use this modified source code in your creation, you must make available the source code of your modifications.
 *
 * You should have received a copy of the GNU Affero General Public License along with the software.
 * If not, please see : <http://www.gnu.org/licenses/>. Full compliance requires reading the terms of this license and following its directives.
    
 */

package org.entcore.auth.services.impl;

import fr.wseduc.webutils.Either;
import fr.wseduc.webutils.Utils;
import io.vertx.core.eventbus.EventBus;
import org.entcore.auth.services.SamlServiceProvider;
import org.entcore.common.neo4j.Neo4j;
import org.entcore.common.neo4j.Neo4jResult;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.xml.XMLObject;
import io.vertx.core.Handler;
import io.vertx.core.eventbus.Message;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public abstract class AbstractSSOProvider implements SamlServiceProvider {

    static final String RETURN_QUERY = "OPTIONAL MATCH (p:Profile) "
            + "WHERE HAS(u.profiles) AND p.name = head(u.profiles) "
            + "RETURN DISTINCT u.id as id, u.activationCode as activationCode, "
            + "u.login as login, u.email as email, u.mobile as mobile, u.federated, u.blocked as blockedUser, p.blocked as blockedProfile ";

    protected boolean validConditions(Assertion assertion, Handler<Either<String, Object>> handler) {
        if (Utils.validationParamsNull(handler, "invalid.assertion", assertion))
            return false;

        Conditions conditions = assertion.getConditions();
        if (conditions.getNotBefore() == null || !conditions.getNotBefore().isBeforeNow()
                || conditions.getNotOnOrAfter() == null || !conditions.getNotOnOrAfter().isAfterNow()) {
            handler.handle(new Either.Left<String, Object>("invalid.conditions"));
            return false;
        }
        return true;
    }

    public void generate(EventBus eb, String userId,
            Handler<Either<String, io.vertx.core.json.JsonArray>> handler) {
        handler.handle(new Either.Left<String, io.vertx.core.json.JsonArray>(
                "Override is required on generate function in AbstractSSOProvider"));
    }

    protected String getAttribute(Assertion assertion, String attr) {
        if (assertion.getAttributeStatements() != null) {
            for (AttributeStatement statement : assertion.getAttributeStatements()) {
                for (Attribute attribute : statement.getAttributes()) {
                    if (attr.equals(attribute.getName())) {
                        for (XMLObject o : attribute.getAttributeValues()) {
                            if (o.getDOM() != null) {
                                return o.getDOM().getTextContent();
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    protected List<String> getAttributes(Assertion assertion, String attr) {
        List<String> attributes = new ArrayList<>();
        if (assertion.getAttributeStatements() != null) {
            for (AttributeStatement statement : assertion.getAttributeStatements()) {
                for (Attribute attribute : statement.getAttributes()) {
                    if (attr.equals(attribute.getName())) {
                        for (XMLObject o : attribute.getAttributeValues()) {
                            if (o.getDOM() != null) {
                                attributes.add(o.getDOM().getTextContent());
                            }
                        }
                    }
                }
            }
        }
        return attributes;
    }

    protected void executeQuery(String query, final JsonObject params,
            final Handler<Either<String, Object>> handler) {
        executeQuery(query, params, null, handler);
    }

    protected void executeQuery(String query, final JsonObject params, final Assertion assertion,
            final Handler<Either<String, Object>> handler) {
        executeFederateQuery(query, params, assertion, Neo4j.getInstance(), handler);
    }

    static void executeFederateQuery(String query, JsonObject params, final Assertion assertion, Neo4j neo4j,
            final Handler<Either<String, Object>> handler) {
        executeFederateQuery(query, params, assertion, true, neo4j, handler);
    }

    static void executeFederateQuery(String query, JsonObject params, final Assertion assertion,
            final boolean setFederated, Neo4j neo4j, final Handler<Either<String, Object>> handler) {
        query += RETURN_QUERY;
        neo4j.execute(query, params,
                Neo4jResult.validUniqueResultHandler(new Handler<Either<String, JsonObject>>() {
                    @Override
                    public void handle(final Either<String, JsonObject> event) {
                        if (event.isRight() && (event.right().getValue().getBoolean("blockedProfile", false)
                                || event.right().getValue().getBoolean("blockedUser", false))) {
                            handler.handle(new Either.Left<String, Object>("blocked.profile"));
                        } else if (setFederated && event.isRight()
                                && event.right().getValue().getBoolean("federated") == null
                                && event.right().getValue().getString("id") != null) {
                            String query = "MATCH (u:User {id: {id}}) SET u.federated = true ";
                            JsonObject params = new JsonObject().put("id",
                                    event.right().getValue().getString("id"));
                            if (assertion != null && assertion.getIssuer() != null
                                    && assertion.getIssuer().getValue() != null
                                    && !assertion.getIssuer().getValue().trim().isEmpty()) {
                                query += ", u.federatedIDP = {idp} ";
                                params.put("idp", assertion.getIssuer().getValue());
                            }
                            Neo4j.getInstance().execute(query, params, new Handler<Message<JsonObject>>() {
                                @Override
                                public void handle(Message<JsonObject> event2) {
                                    handler.handle(new Either.Right<String, Object>(event.right().getValue()));
                                }
                            });
                        } else if (event.isRight()) {
                            handler.handle(new Either.Right<String, Object>(event.right().getValue()));
                        } else {
                            handler.handle(new Either.Left<String, Object>(event.left().getValue()));
                        }
                    }
                }));
    }

    protected void executeMultiVectorQuery(String query, JsonObject params, final Assertion assertion,
            final Handler<Either<String, Object>> handler) {
        query += (RETURN_QUERY + ", s.name as structureName");
        Neo4j.getInstance().execute(query, params,
                Neo4jResult.validResultHandler(new Handler<Either<String, JsonArray>>() {
                    @Override
                    public void handle(final Either<String, JsonArray> event) {
                        if (event.isRight()) {
                            JsonArray ids = new fr.wseduc.webutils.collections.JsonArray();
                            final Set<String> userIds = new HashSet<>();
                            final JsonArray users = event.right().getValue();
                            for (Object o : users) {
                                if (!(o instanceof JsonObject))
                                    continue;
                                JsonObject j = (JsonObject) o;
                                if (j.getBoolean("blockedProfile", false)) {
                                    handler.handle(new Either.Left<String, Object>("blocked.profile"));
                                    return;
                                }
                                userIds.add(j.getString("id"));
                                if (Utils.isNotEmpty(j.getString("id")) && !j.getBoolean("federated", false)) {
                                    ids.add(j.getString("id"));
                                }
                            }
                            if (ids.size() > 0) {
                                String query = "MATCH (u:User) WHERE u.id IN {ids} SET u.federated = true ";
                                JsonObject params = new JsonObject().put("ids", ids);
                                if (assertion != null && assertion.getIssuer() != null
                                        && assertion.getIssuer().getValue() != null
                                        && !assertion.getIssuer().getValue().trim().isEmpty()) {
                                    query += ", u.federatedIDP = {idp} ";
                                    params.put("idp", assertion.getIssuer().getValue());
                                }
                                Neo4j.getInstance().execute(query, params, new Handler<Message<JsonObject>>() {
                                    @Override
                                    public void handle(Message<JsonObject> event2) {
                                        if (userIds.size() == 1) {
                                            handler.handle(
                                                    new Either.Right<String, Object>(users.getJsonObject(0)));
                                        } else {
                                            handler.handle(new Either.Right<String, Object>(users));
                                        }
                                    }
                                });
                            } else {
                                if (userIds.size() == 1) {
                                    handler.handle(new Either.Right<String, Object>(users.getJsonObject(0)));
                                } else {
                                    handler.handle(new Either.Right<String, Object>(users));
                                }
                            }
                        } else {
                            handler.handle(new Either.Left<String, Object>(event.left().getValue()));
                        }
                    }
                }));
    }

}