org.entcore.directory.services.impl.DefaultClassService.java Source code

Java tutorial

Introduction

Here is the source code for org.entcore.directory.services.impl.DefaultClassService.java

Source

/* Copyright  "Open Digital Education", 2014
 *
 * 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.directory.services.impl;

import fr.wseduc.webutils.Either;

import org.entcore.common.neo4j.Neo4j;
import org.entcore.common.neo4j.Neo4jResult;
import org.entcore.common.user.UserInfos;
import org.entcore.common.user.UserUtils;
import org.entcore.directory.Directory;
import org.entcore.directory.services.ClassService;
import io.vertx.core.Handler;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.Message;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.List;

import static fr.wseduc.webutils.Utils.handlerToAsyncHandler;
import static org.entcore.common.neo4j.Neo4jResult.validResultHandler;
import static org.entcore.common.neo4j.Neo4jResult.validUniqueResultHandler;
import static org.entcore.common.user.DefaultFunctions.ADMIN_LOCAL;
import static org.entcore.common.user.DefaultFunctions.CLASS_ADMIN;
import static org.entcore.common.user.DefaultFunctions.SUPER_ADMIN;

public class DefaultClassService implements ClassService {

    private final Neo4j neo = Neo4j.getInstance();
    private final EventBus eb;

    public DefaultClassService(EventBus eb) {
        this.eb = eb;
    }

    @Override
    public void create(String schoolId, JsonObject classe, final Handler<Either<String, JsonObject>> result) {
        JsonObject action = new JsonObject().put("action", "manual-create-class").put("structureId", schoolId)
                .put("data", classe);
        eb.send(Directory.FEEDER, action, handlerToAsyncHandler(validUniqueResultHandler(result)));
    }

    @Override
    public void update(String classId, JsonObject classe, Handler<Either<String, JsonObject>> result) {
        JsonObject action = new JsonObject().put("action", "manual-update-class").put("classId", classId)
                .put("data", classe);
        eb.send(Directory.FEEDER, action, handlerToAsyncHandler(validUniqueResultHandler(result)));
    }

    @Override
    public void findUsers(String classId, JsonArray expectedTypes, Handler<Either<String, JsonArray>> results) {
        String filter;
        JsonObject params = new JsonObject().put("classId", classId);
        if (expectedTypes == null || expectedTypes.size() < 1) {
            filter = "";
        } else {
            filter = "WHERE p.name IN {expected} ";
            params.put("expected", expectedTypes);
        }
        String query = "MATCH (c:`Class` { id : {classId}})<-[:DEPENDS]-(cpg:ProfileGroup)"
                + "-[:DEPENDS]->(spg:ProfileGroup)-[:HAS_PROFILE]->(p:Profile), cpg<-[:IN]-(m:User) " + filter
                + "RETURN distinct m.lastName as lastName, m.firstName as firstName, m.id as id, "
                + "CASE WHEN m.loginAlias IS NOT NULL THEN m.loginAlias ELSE m.login END as login, m.activationCode as activationCode, m.birthDate as birthDate, "
                + "p.name as type, m.blocked as blocked, m.source as source " + "ORDER BY type, lastName ";
        neo.execute(query, params, validResultHandler(results));
    }

    @Override
    public void get(String classId, Handler<Either<String, JsonObject>> result) {
        if (validationParamsError(result, classId))
            return;
        String query = "MATCH (c:`Class` { id : {classId}}) RETURN c.id as id, c.externalId as externalId,  c.name as name, c.level as level";
        neo.execute(query, new JsonObject().put("classId", classId), validUniqueResultHandler(result));
    }

    @Override
    public void addUser(final String classId, final String userId, final UserInfos user,
            final Handler<Either<String, JsonObject>> result) {
        if (validationParamsError(result, classId, userId))
            return;
        if (user == null) {
            result.handle(new Either.Left<String, JsonObject>("invalid.userinfos"));
            return;
        }
        neo.execute(
                "MATCH (u:`User` {id : {id}})-[:IN]->(pg:ProfileGroup)-[:HAS_PROFILE]->(p:Profile) "
                        + "RETURN distinct p.name as type",
                new JsonObject().put("id", userId), new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> r) {
                        JsonArray res = r.body().getJsonArray("result");
                        if ("ok".equals(r.body().getString("status")) && res != null && res.size() == 1) {
                            final String t = (res.getJsonObject(0)).getString("type");
                            String customReturn = "MATCH (c:`Class` { id : {classId}})<-[:DEPENDS]-(cpg:ProfileGroup)"
                                    + "-[:DEPENDS]->(spg:ProfileGroup)-[:HAS_PROFILE]->(p:Profile {name : {profile}}), "
                                    + "c-[:BELONGS]->(s:Structure) " + "WHERE visibles.id = {uId} "
                                    + "CREATE UNIQUE visibles-[:IN]->cpg "
                                    + "RETURN DISTINCT visibles.id as id, s.id as schoolId";
                            JsonObject params = new JsonObject().put("classId", classId).put("uId", userId)
                                    .put("profile", t);
                            UserUtils.findVisibleUsers(eb, user.getUserId(), false, customReturn, params,
                                    new Handler<JsonArray>() {

                                        @Override
                                        public void handle(final JsonArray users) {
                                            if (users != null && users.size() == 1) {
                                                if ("Student".equals(t)) {
                                                    String query = "MATCH (c:`Class` { id : {classId}})<-[:DEPENDS]-(cpg:ProfileGroup)-[:DEPENDS]->(spg:ProfileGroup)"
                                                            + "-[:HAS_PROFILE]->(p:Profile {name : 'Relative'}), "
                                                            + "(u:User {id: {uId}})-[:RELATED]->(relative: User) "
                                                            + "CREATE UNIQUE relative-[:IN]->cpg "
                                                            + "RETURN count(relative) as relativeNb";

                                                    JsonObject params = new JsonObject().put("classId", classId)
                                                            .put("uId", userId);

                                                    neo.execute(query, params, Neo4jResult.validEmptyHandler(
                                                            new Handler<Either<String, JsonObject>>() {
                                                                public void handle(
                                                                        Either<String, JsonObject> event) {
                                                                    if (event.isLeft()) {
                                                                        result.handle(
                                                                                new Either.Left<String, JsonObject>(
                                                                                        "error.while.attaching.relatives"));
                                                                    } else {
                                                                        result.handle(
                                                                                new Either.Right<String, JsonObject>(
                                                                                        users.getJsonObject(0)));
                                                                    }
                                                                }
                                                            }));
                                                } else {
                                                    result.handle(new Either.Right<String, JsonObject>(
                                                            users.getJsonObject(0)));
                                                }
                                            } else {
                                                result.handle(
                                                        new Either.Left<String, JsonObject>("user.not.visible"));
                                            }
                                        }
                                    });
                        } else {
                            result.handle(new Either.Left<String, JsonObject>("invalid.user"));
                        }
                    }
                });
    }

    @Override
    public void link(String classId, String userId, Handler<Either<String, JsonObject>> result) {
        JsonObject action = new JsonObject().put("action", "manual-add-user").put("classId", classId).put("userId",
                userId);
        eb.send(Directory.FEEDER, action, handlerToAsyncHandler(validUniqueResultHandler(result)));
    }

    @Override
    public void unlink(String classId, String userId, Handler<Either<String, JsonObject>> result) {
        JsonObject action = new JsonObject().put("action", "manual-remove-user").put("classId", classId)
                .put("userId", userId);
        eb.send(Directory.FEEDER, action, handlerToAsyncHandler(validUniqueResultHandler(result)));
    }

    @Override
    public void listAdmin(String structureId, UserInfos userInfos, Handler<Either<String, JsonArray>> results) {
        if (userInfos == null) {
            results.handle(new Either.Left<String, JsonArray>("invalid.user"));
            return;
        }
        String condition = "";
        JsonObject params = new JsonObject();
        if (!userInfos.getFunctions().containsKey(SUPER_ADMIN) && !userInfos.getFunctions().containsKey(ADMIN_LOCAL)
                && !userInfos.getFunctions().containsKey(CLASS_ADMIN)) {
            results.handle(new Either.Left<String, JsonArray>("forbidden"));
            return;
        } else if (userInfos.getFunctions().containsKey(ADMIN_LOCAL)
                || userInfos.getFunctions().containsKey(CLASS_ADMIN)) {
            UserInfos.Function f = userInfos.getFunctions().get(ADMIN_LOCAL);
            List<String> scope = f.getScope();
            if (scope != null && !scope.isEmpty()) {
                condition = "WHERE (s.id IN {scope} OR c.id IN {scope}";
                params.put("scope", new fr.wseduc.webutils.collections.JsonArray(scope));
            }
        }

        if (structureId != null && !structureId.trim().isEmpty()) {
            if (condition.isEmpty()) {
                condition = "WHERE s.id = {structure} ";
            } else {
                condition += ") AND s.id = {structure} ";
            }
            params.put("structure", structureId);
        } else if (!condition.isEmpty()) {
            condition += ") ";
        }
        String query = "MATCH (c:Class)-[:BELONGS]->(s:Structure) " + condition
                + "RETURN c.id as id, c.name as name , c.externalId as externalId";
        neo.execute(query, params, validResultHandler(results));
    }

    private boolean validationParamsError(Handler<Either<String, JsonObject>> result, String... params) {
        if (params.length > 0) {
            for (String s : params) {
                if (s == null) {
                    result.handle(new Either.Left<String, JsonObject>("school.invalid.parameter"));
                    return true;
                }
            }
        }
        return false;
    }

}