Search in sources :

Example 51 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class VosManagerBlImpl method findCandidates.

public List<Candidate> findCandidates(PerunSession sess, Vo vo, String searchString, int maxNumOfResults, List<ExtSource> extSources, boolean filterExistingMembers) {
    List<Candidate> candidates = new ArrayList<>();
    int numOfResults = 0;
    try {
        // Iterate through given extSources
        for (ExtSource source : extSources) {
            try {
                // Info if this is only simple ext source, change behavior if not
                boolean simpleExtSource = true;
                // Get potential subjects from the extSource
                List<Map<String, String>> subjects;
                try {
                    if (source instanceof ExtSourceApi) {
                        // find subjects with all their properties
                        subjects = ((ExtSourceApi) source).findSubjects(searchString, maxNumOfResults);
                        simpleExtSource = false;
                    } else {
                        // find subjects only with logins - they then must be retrieved by login
                        subjects = ((ExtSourceSimpleApi) source).findSubjectsLogins(searchString, maxNumOfResults);
                    }
                } catch (ExtSourceUnsupportedOperationException e1) {
                    log.warn("ExtSource {} doesn't support findSubjects", source.getName());
                    continue;
                } catch (InternalErrorException e) {
                    log.error("Error occurred on ExtSource {},  Exception {}.", source.getName(), e);
                    continue;
                } finally {
                    try {
                        ((ExtSourceSimpleApi) source).close();
                    } catch (ExtSourceUnsupportedOperationException e) {
                    // ExtSource doesn't support that functionality, so silently skip it.
                    } catch (InternalErrorException e) {
                        log.error("Can't close extSource connection.", e);
                    }
                }
                Set<String> uniqueLogins = new HashSet<>();
                for (Map<String, String> s : subjects) {
                    // Check if the user has unique identifier within extSource
                    if ((s.get("login") == null) || (s.get("login") != null && s.get("login").isEmpty())) {
                        log.error("User '{}' cannot be added, because he/she doesn't have a unique identifier (login)", s);
                        // Skip to another user
                        continue;
                    }
                    String extLogin = s.get("login");
                    // check uniqueness of every login in extSource
                    if (uniqueLogins.contains(extLogin)) {
                        throw new InternalErrorException("There are more than 1 login '" + extLogin + "' getting from extSource '" + source + "'");
                    } else {
                        uniqueLogins.add(extLogin);
                    }
                    // Get Candidate
                    Candidate candidate;
                    try {
                        if (simpleExtSource) {
                            // retrieve data about subjects from ext source based on ext. login
                            candidate = new Candidate(getPerunBl().getExtSourcesManagerBl().getCandidate(sess, source, extLogin));
                        } else {
                            // retrieve data about subjects from subjects we already have locally
                            candidate = new Candidate(getPerunBl().getExtSourcesManagerBl().getCandidate(sess, s, source, extLogin));
                        }
                    } catch (CandidateNotExistsException e) {
                        throw new ConsistencyErrorException("findSubjects returned that candidate, but getCandidate cannot find him using login " + extLogin, e);
                    } catch (ExtSourceUnsupportedOperationException e) {
                        throw new InternalErrorException("extSource supports findSubjects but not getCandidate???", e);
                    }
                    if (filterExistingMembers) {
                        try {
                            getPerunBl().getMembersManagerBl().getMemberByUserExtSources(sess, vo, candidate.getUserExtSources());
                            // Candidate is already a member of the VO, so do not add him to the list of candidates
                            continue;
                        } catch (MemberNotExistsException e) {
                        // This is OK
                        }
                    }
                    // Add candidate to the list of candidates
                    log.debug("findCandidates: returning candidate: {}", candidate);
                    candidates.add(candidate);
                    numOfResults++;
                    // Stop getting new members if the number of already retrieved members exceeded the maxNumOfResults
                    if (maxNumOfResults > 0 && numOfResults >= maxNumOfResults) {
                        break;
                    }
                }
            } catch (InternalErrorException e) {
                log.error("Failed to get candidates from ExtSource: {}", source);
            } finally {
                if (source instanceof ExtSourceSimpleApi) {
                    try {
                        ((ExtSourceSimpleApi) source).close();
                    } catch (ExtSourceUnsupportedOperationException e) {
                    // silently skip
                    } catch (Exception e) {
                        log.error("Failed to close connection to extsource", e);
                    }
                }
            }
            // Stop walking through next sources if the number of already retrieved members exceeded the maxNumOfResults
            if (maxNumOfResults > 0 && numOfResults >= maxNumOfResults) {
                break;
            }
        }
        log.debug("Returning {} potential members for vo {}", candidates.size(), vo);
        return candidates;
    } catch (RuntimeException e) {
        throw new InternalErrorException(e);
    }
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) MemberCandidate(cz.metacentrum.perun.core.api.MemberCandidate) ConsistencyErrorException(cz.metacentrum.perun.core.api.exceptions.ConsistencyErrorException) MemberNotExistsException(cz.metacentrum.perun.core.api.exceptions.MemberNotExistsException) ArrayList(java.util.ArrayList) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) ExtSourceApi(cz.metacentrum.perun.core.implApi.ExtSourceApi) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) MemberNotExistsException(cz.metacentrum.perun.core.api.exceptions.MemberNotExistsException) GroupExistsException(cz.metacentrum.perun.core.api.exceptions.GroupExistsException) UserNotAdminException(cz.metacentrum.perun.core.api.exceptions.UserNotAdminException) LoginNotExistsException(cz.metacentrum.perun.core.api.exceptions.LoginNotExistsException) RelationExistsException(cz.metacentrum.perun.core.api.exceptions.RelationExistsException) CandidateNotExistsException(cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException) VoExistsException(cz.metacentrum.perun.core.api.exceptions.VoExistsException) AttributeNotExistsException(cz.metacentrum.perun.core.api.exceptions.AttributeNotExistsException) RoleCannotBeManagedException(cz.metacentrum.perun.core.api.exceptions.RoleCannotBeManagedException) MemberNotSponsoredException(cz.metacentrum.perun.core.api.exceptions.MemberNotSponsoredException) AlreadySponsorException(cz.metacentrum.perun.core.api.exceptions.AlreadySponsorException) ConsistencyErrorException(cz.metacentrum.perun.core.api.exceptions.ConsistencyErrorException) GroupNotAdminException(cz.metacentrum.perun.core.api.exceptions.GroupNotAdminException) ExtSourceUnsupportedOperationException(cz.metacentrum.perun.core.api.exceptions.ExtSourceUnsupportedOperationException) NotGroupMemberException(cz.metacentrum.perun.core.api.exceptions.NotGroupMemberException) AlreadyAdminException(cz.metacentrum.perun.core.api.exceptions.AlreadyAdminException) UserNotInRoleException(cz.metacentrum.perun.core.api.exceptions.UserNotInRoleException) BanNotExistsException(cz.metacentrum.perun.core.api.exceptions.BanNotExistsException) VoNotExistsException(cz.metacentrum.perun.core.api.exceptions.VoNotExistsException) UserNotExistsException(cz.metacentrum.perun.core.api.exceptions.UserNotExistsException) PerunException(cz.metacentrum.perun.core.api.exceptions.PerunException) ExtSource(cz.metacentrum.perun.core.api.ExtSource) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) ExtSourceUnsupportedOperationException(cz.metacentrum.perun.core.api.exceptions.ExtSourceUnsupportedOperationException) Map(java.util.Map) HashMap(java.util.HashMap) ExtSourceSimpleApi(cz.metacentrum.perun.core.implApi.ExtSourceSimpleApi) HashSet(java.util.HashSet) CandidateNotExistsException(cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException)

Example 52 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class VosManagerBlImpl method findCandidates.

public List<Candidate> findCandidates(PerunSession sess, Group group, String searchString) throws InternalErrorException {
    List<Candidate> candidates = new ArrayList<>();
    try {
        // Iterate through all registered extSources in the group
        for (ExtSource source : getPerunBl().getExtSourcesManagerBl().getGroupExtSources(sess, group)) {
            // Info if this is only simple ext source, change behavior if not
            boolean simpleExtSource = true;
            // Get potential subjects from the extSource
            List<Map<String, String>> subjects;
            try {
                if (source instanceof ExtSourceApi) {
                    // find subjects with all their properties
                    subjects = ((ExtSourceApi) source).findSubjects(searchString);
                    simpleExtSource = false;
                } else {
                    // find subjects only with logins - they then must be retrieved by login
                    subjects = ((ExtSourceSimpleApi) source).findSubjectsLogins(searchString);
                }
            } catch (ExtSourceUnsupportedOperationException e1) {
                log.warn("ExtSource {} doesn't support findSubjects", source.getName());
                continue;
            } catch (InternalErrorException e) {
                log.error("Error occurred on ExtSource {},  Exception {}.", source.getName(), e);
                continue;
            } finally {
                try {
                    ((ExtSourceSimpleApi) source).close();
                } catch (ExtSourceUnsupportedOperationException e) {
                // ExtSource doesn't support that functionality, so silently skip it.
                } catch (InternalErrorException e) {
                    log.error("Can't close extSource connection. Cause: {}", e);
                }
            }
            Set<String> uniqueLogins = new HashSet<>();
            for (Map<String, String> s : subjects) {
                // Check if the user has unique identifier within extSource
                if ((s.get("login") == null) || (s.get("login") != null && ((String) s.get("login")).isEmpty())) {
                    log.error("User '{}' cannot be added, because he/she doesn't have a unique identifier (login)", s);
                    // Skip to another user
                    continue;
                }
                String extLogin = (String) s.get("login");
                // check uniqueness of every login in extSource
                if (uniqueLogins.contains(extLogin)) {
                    throw new InternalErrorException("There are more than 1 login '" + extLogin + "' getting from extSource '" + source + "'");
                } else {
                    uniqueLogins.add(extLogin);
                }
                // Get Candidate
                Candidate candidate;
                try {
                    if (simpleExtSource) {
                        // retrieve data about subjects from ext source based on ext. login
                        candidate = getPerunBl().getExtSourcesManagerBl().getCandidate(sess, source, extLogin);
                    } else {
                        // retrieve data about subjects from subjects we already have locally
                        candidate = getPerunBl().getExtSourcesManagerBl().getCandidate(sess, s, source, extLogin);
                    }
                } catch (ExtSourceNotExistsException e) {
                    throw new ConsistencyErrorException("Getting candidate from non-existing extSource " + source, e);
                } catch (CandidateNotExistsException e) {
                    throw new ConsistencyErrorException("findSubjects returned that candidate, but getCandidate cannot find him using login " + extLogin, e);
                } catch (ExtSourceUnsupportedOperationException e) {
                    throw new InternalErrorException("extSource supports findSubjects but not getCandidate???", e);
                }
                try {
                    Vo vo = getPerunBl().getVosManagerBl().getVoById(sess, group.getVoId());
                    getPerunBl().getMembersManagerBl().getMemberByUserExtSources(sess, vo, candidate.getUserExtSources());
                    // Candidate is already a member of the VO, so do not add him to the list of candidates
                    continue;
                } catch (VoNotExistsException e) {
                    throw new InternalErrorException(e);
                } catch (MemberNotExistsException e) {
                // This is OK
                }
                // Add candidate to the list of candidates
                log.debug("findCandidates: returning candidate: {}", candidate);
                candidates.add(candidate);
            }
        }
        log.debug("Returning {} potential members for group {}", candidates.size(), group);
        return candidates;
    } catch (RuntimeException e) {
        throw new InternalErrorException(e);
    }
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) ConsistencyErrorException(cz.metacentrum.perun.core.api.exceptions.ConsistencyErrorException) MemberNotExistsException(cz.metacentrum.perun.core.api.exceptions.MemberNotExistsException) ArrayList(java.util.ArrayList) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) ExtSourceApi(cz.metacentrum.perun.core.implApi.ExtSourceApi) VoNotExistsException(cz.metacentrum.perun.core.api.exceptions.VoNotExistsException) Vo(cz.metacentrum.perun.core.api.Vo) ExtSource(cz.metacentrum.perun.core.api.ExtSource) ExtSourceUnsupportedOperationException(cz.metacentrum.perun.core.api.exceptions.ExtSourceUnsupportedOperationException) ExtSourceNotExistsException(cz.metacentrum.perun.core.api.exceptions.ExtSourceNotExistsException) Map(java.util.Map) ExtSourceSimpleApi(cz.metacentrum.perun.core.implApi.ExtSourceSimpleApi) HashSet(java.util.HashSet) CandidateNotExistsException(cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException)

Example 53 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class MembersManagerBlImpl method createSponsoredAccount.

public Member createSponsoredAccount(PerunSession sess, Map<String, String> params, String namespace, ExtSource extSource, String extSourcePostfix, User owner, Vo vo, int loa) throws InternalErrorException, PasswordCreationFailedException, PasswordOperationTimeoutException, PasswordStrengthFailedException, GroupOperationsException, ExtendMembershipException, AlreadyMemberException, WrongReferenceAttributeValueException, WrongAttributeValueException, UserNotExistsException, ExtSourceNotExistsException, LoginNotExistsException {
    String loginNamespaceUri = AttributesManager.NS_USER_ATTR_DEF + ":login-namespace:" + namespace;
    boolean passwordPresent = params.get("password") != null;
    if (params.get(loginNamespaceUri) == null) {
        Map<String, String> generatedParams = getPerunBl().getUsersManagerBl().generateAccount(sess, namespace, params);
        params.putAll(generatedParams);
    } else if (passwordPresent) {
        getPerunBl().getUsersManagerBl().reservePassword(sess, params.get(loginNamespaceUri), namespace, params.get("password"));
    } else {
        throw new InternalErrorException("If login for new account is provided, password must be provided also");
    }
    Iterator<String> iterator = params.keySet().iterator();
    // remove non-valid entries from map for Candidate otherwise it would fail to create member
    while (iterator.hasNext()) {
        String next = iterator.next();
        if (!next.startsWith("urn:perun:user") && !next.startsWith("urn:perun:member")) {
            iterator.remove();
        }
    }
    String extSourceLogin = params.get(loginNamespaceUri) + extSourcePostfix;
    UserExtSource userExtSource = new UserExtSource(extSource, loa, extSourceLogin);
    Candidate candidate = new Candidate(userExtSource, params);
    Member member = this.createSpecificMember(sess, vo, candidate, Arrays.asList(owner), SpecificUserType.SPONSORED);
    this.validateMemberAsync(sess, member);
    if (passwordPresent) {
        User user = getPerunBl().getUsersManagerBl().getUserById(sess, member.getUserId());
        getPerunBl().getUsersManagerBl().validatePasswordAndSetExtSources(sess, user, params.get(loginNamespaceUri), namespace);
    }
    return member;
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) User(cz.metacentrum.perun.core.api.User) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) RichMember(cz.metacentrum.perun.core.api.RichMember) Member(cz.metacentrum.perun.core.api.Member)

Example 54 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class ExtSourcesManagerBlImpl method getCandidate.

@Override
public Candidate getCandidate(PerunSession sess, ExtSource source, String login) throws InternalErrorException, ExtSourceNotExistsException, CandidateNotExistsException, ExtSourceUnsupportedOperationException {
    // New Canddate
    Candidate candidate = new Candidate();
    // Prepare userExtSource object
    UserExtSource userExtSource = new UserExtSource();
    userExtSource.setExtSource(source);
    userExtSource.setLogin(login);
    // Set the userExtSource
    candidate.setUserExtSource(userExtSource);
    // Get the subject from the extSource
    Map<String, String> subject = null;
    try {
        subject = ((ExtSourceSimpleApi) source).getSubjectByLogin(login);
    } catch (SubjectNotExistsException e) {
        throw new CandidateNotExistsException(login);
    }
    if (subject == null) {
        throw new CandidateNotExistsException("Candidate with login [" + login + "] not exists");
    }
    //If first name of candidate is not in format of name, set null instead
    candidate.setFirstName(subject.get("firstName"));
    if (candidate.getFirstName() != null) {
        Matcher name = namePattern.matcher(candidate.getFirstName());
        if (!name.matches())
            candidate.setFirstName(null);
    }
    //If last name of candidate is not in format of name, set null instead
    candidate.setLastName(subject.get("lastName"));
    if (candidate.getLastName() != null) {
        Matcher name = namePattern.matcher(candidate.getLastName());
        if (!name.matches())
            candidate.setLastName(null);
    }
    candidate.setMiddleName(subject.get("middleName"));
    candidate.setTitleAfter(subject.get("titleAfter"));
    candidate.setTitleBefore(subject.get("titleBefore"));
    //Set service user
    if (subject.get("isServiceUser") == null) {
        candidate.setServiceUser(false);
    } else {
        String isServiceUser = subject.get("isServiceUser");
        if (isServiceUser.equals("true")) {
            candidate.setServiceUser(true);
        } else {
            candidate.setServiceUser(false);
        }
    }
    //Set sponsored user
    if (subject.get("isSponsoredUser") == null) {
        candidate.setSponsoredUser(false);
    } else {
        String isSponsoredUser = subject.get("isSponsoredUser");
        if (isSponsoredUser.equals("true")) {
            candidate.setSponsoredUser(true);
        } else {
            candidate.setSponsoredUser(false);
        }
    }
    // Additional userExtSources
    List<UserExtSource> additionalUserExtSources = new ArrayList<UserExtSource>();
    // Filter attributes
    Map<String, String> attributes = new HashMap<String, String>();
    for (String attrName : subject.keySet()) {
        // FIXME volat metody z attributesManagera nez kontrolovat na zacatek jmena
        if (attrName.startsWith(AttributesManager.NS_MEMBER_ATTR) || attrName.startsWith(AttributesManager.NS_USER_ATTR)) {
            attributes.put(attrName, subject.get(attrName));
        } else if (attrName.startsWith(ExtSourcesManagerImpl.USEREXTSOURCEMAPPING)) {
            //skip null additional ext sources
            if (subject.get(attrName) == null)
                continue;
            // Add additionalUserExtSources
            // Entry contains extSourceName|extSourceType|extLogin[|LoA]
            String[] userExtSourceRaw = subject.get(attrName).split("\\|");
            log.debug("Processing additionalUserExtSource {}", subject.get(attrName));
            //Check if the array has at least 3 parts, this is protection against outOfBoundException
            if (userExtSourceRaw.length < 3) {
                throw new InternalErrorException("There is missing some mandatory part of additional user extSource value when processing it - '" + attrName + "'");
            }
            String additionalExtSourceName = userExtSourceRaw[0];
            String additionalExtSourceType = userExtSourceRaw[1];
            String additionalExtLogin = userExtSourceRaw[2];
            int additionalExtLoa = 0;
            //Loa is not mandatory argument
            if (userExtSourceRaw.length > 3 && userExtSourceRaw[3] != null) {
                try {
                    additionalExtLoa = Integer.parseInt(userExtSourceRaw[3]);
                } catch (NumberFormatException e) {
                    throw new ParserException("Candidate with login [" + login + "] has wrong LoA '" + userExtSourceRaw[3] + "'.", e, "LoA");
                }
            }
            ExtSource additionalExtSource;
            if (additionalExtSourceName == null || additionalExtSourceName.isEmpty() || additionalExtSourceType == null || additionalExtSourceType.isEmpty() || additionalExtLogin == null || additionalExtLogin.isEmpty()) {
                log.error("User with login {} has invalid additional userExtSource defined {}.", login, userExtSourceRaw);
            } else {
                try {
                    // Try to get extSource, with full extSource object (containg ID)
                    additionalExtSource = getPerunBl().getExtSourcesManagerBl().getExtSourceByName(sess, additionalExtSourceName);
                } catch (ExtSourceNotExistsException e) {
                    try {
                        // Create new one if not exists
                        additionalExtSource = new ExtSource(additionalExtSourceName, additionalExtSourceType);
                        additionalExtSource = getPerunBl().getExtSourcesManagerBl().createExtSource(sess, additionalExtSource, null);
                    } catch (ExtSourceExistsException e1) {
                        throw new ConsistencyErrorException("Creating existin extSource: " + additionalExtSourceName);
                    }
                }
                //add additional user extSource
                additionalUserExtSources.add(new UserExtSource(additionalExtSource, additionalExtLoa, additionalExtLogin));
            }
        }
    }
    candidate.setAdditionalUserExtSources(additionalUserExtSources);
    candidate.setAttributes(attributes);
    return candidate;
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) ParserException(cz.metacentrum.perun.core.api.exceptions.ParserException) ConsistencyErrorException(cz.metacentrum.perun.core.api.exceptions.ConsistencyErrorException) Matcher(java.util.regex.Matcher) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) ExtSourceExistsException(cz.metacentrum.perun.core.api.exceptions.ExtSourceExistsException) SubjectNotExistsException(cz.metacentrum.perun.core.api.exceptions.SubjectNotExistsException) ExtSource(cz.metacentrum.perun.core.api.ExtSource) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource) ExtSourceNotExistsException(cz.metacentrum.perun.core.api.exceptions.ExtSourceNotExistsException) CandidateNotExistsException(cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException)

Example 55 with Candidate

use of cz.metacentrum.perun.core.api.Candidate in project perun by CESNET.

the class MembersManagerEntryIntegrationTest method setUpCandidateSponsor2.

private Candidate setUpCandidateSponsor2() {
    String userFirstName = "Pavel";
    String userLastName = "Sponzor2";
    String extLogin = "bbbbb";
    // Mockito.mock(Candidate.class);
    Candidate candidate = new Candidate();
    candidate.setFirstName(userFirstName);
    candidate.setId(0);
    candidate.setMiddleName("");
    candidate.setLastName(userLastName);
    candidate.setTitleBefore("");
    candidate.setTitleAfter("");
    final UserExtSource userExtSource = new UserExtSource(extSource, extLogin);
    candidate.setUserExtSource(userExtSource);
    candidate.setAttributes(new HashMap<>());
    return candidate;
}
Also used : Candidate(cz.metacentrum.perun.core.api.Candidate) UserExtSource(cz.metacentrum.perun.core.api.UserExtSource)

Aggregations

Candidate (cz.metacentrum.perun.core.api.Candidate)100 UserExtSource (cz.metacentrum.perun.core.api.UserExtSource)52 Test (org.junit.Test)41 Member (cz.metacentrum.perun.core.api.Member)37 AbstractPerunIntegrationTest (cz.metacentrum.perun.core.AbstractPerunIntegrationTest)30 ExtSource (cz.metacentrum.perun.core.api.ExtSource)25 RichMember (cz.metacentrum.perun.core.api.RichMember)24 User (cz.metacentrum.perun.core.api.User)23 HashMap (java.util.HashMap)23 ArrayList (java.util.ArrayList)21 Group (cz.metacentrum.perun.core.api.Group)15 Attribute (cz.metacentrum.perun.core.api.Attribute)14 Map (java.util.Map)12 MemberCandidate (cz.metacentrum.perun.core.api.MemberCandidate)11 RichUser (cz.metacentrum.perun.core.api.RichUser)11 Vo (cz.metacentrum.perun.core.api.Vo)11 LinkedHashMap (java.util.LinkedHashMap)11 RichUserExtSource (cz.metacentrum.perun.core.api.RichUserExtSource)9 InternalErrorException (cz.metacentrum.perun.core.api.exceptions.InternalErrorException)9 CandidateNotExistsException (cz.metacentrum.perun.core.api.exceptions.CandidateNotExistsException)8