package cz.metacentrum.perun.core.impl.modules.pwdmgr;

import cz.metacentrum.perun.core.api.Attribute;
import cz.metacentrum.perun.core.api.AttributesManager;
import cz.metacentrum.perun.core.api.ExtSource;
import cz.metacentrum.perun.core.api.PerunSession;
import cz.metacentrum.perun.core.api.User;
import cz.metacentrum.perun.core.api.UserExtSource;
import cz.metacentrum.perun.core.api.exceptions.AttributeNotExistsException;
import cz.metacentrum.perun.core.api.exceptions.ExtSourceNotExistsException;
import cz.metacentrum.perun.core.api.exceptions.InternalErrorException;
import cz.metacentrum.perun.core.api.exceptions.InvalidLoginException;
import cz.metacentrum.perun.core.api.exceptions.UserExtSourceExistsException;
import cz.metacentrum.perun.core.api.exceptions.WrongAttributeAssignmentException;
import cz.metacentrum.perun.core.api.exceptions.WrongAttributeValueException;
import cz.metacentrum.perun.core.api.exceptions.WrongReferenceAttributeValueException;
import cz.metacentrum.perun.core.bl.PerunBl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * Password manager for ICS-MUNI-CZ login-namespace.
 */
public class IcsmuniczPasswordManagerModule extends GenericPasswordManagerModule {

	private final static Logger log = LoggerFactory.getLogger(EinfraPasswordManagerModule.class);

	public IcsmuniczPasswordManagerModule() {
		// set proper namespace
		this.actualLoginNamespace = "ics-muni-cz";
	}

	@Override
	public void validatePassword(PerunSession sess, String userLogin, User user) throws InvalidLoginException {
		if (user == null) {
			user = ((PerunBl) sess.getPerun()).getModulesUtilsBl().getUserByLoginInNamespace(sess, userLogin, actualLoginNamespace);
		}

		if (user == null) {
			log.warn("No user was found by login '{}' in {} namespace.", userLogin, actualLoginNamespace);
		} else {
			// set extSources and extSource related attributes
			try {
				List<String> kerberosLogins = new ArrayList<>();

				ExtSource extSource = ((PerunBl) sess.getPerun()).getExtSourcesManagerBl().getExtSourceByName(sess, "ICS.MUNI.CZ");
				UserExtSource ues = new UserExtSource(extSource, userLogin + "@ICS.MUNI.CZ");
				ues.setLoa(0);

				try {
					((PerunBl) sess.getPerun()).getUsersManagerBl().addUserExtSource(sess, user, ues);
				} catch (UserExtSourceExistsException ex) {
					//this is OK
				}

				// Store also Kerberos logins
				Attribute kerberosLoginsAttr = ((PerunBl) sess.getPerun()).getAttributesManagerBl().getAttribute(sess, user, AttributesManager.NS_USER_ATTR_DEF + ":" + "kerberosLogins");
				if (kerberosLoginsAttr != null && kerberosLoginsAttr.getValue() != null) {
					kerberosLogins.addAll((List<String>) kerberosLoginsAttr.getValue());
				}

				if (!kerberosLogins.contains(userLogin + "@ICS.MUNI.CZ") && kerberosLoginsAttr != null) {
					kerberosLogins.add(userLogin + "@ICS.MUNI.CZ");
					kerberosLoginsAttr.setValue(kerberosLogins);
					((PerunBl) sess.getPerun()).getAttributesManagerBl().setAttribute(sess, user, kerberosLoginsAttr);
				}
			} catch (WrongAttributeAssignmentException | AttributeNotExistsException | ExtSourceNotExistsException | WrongAttributeValueException | WrongReferenceAttributeValueException ex) {
				throw new InternalErrorException(ex);
			}
		}

		// validate password
		super.validatePassword(sess, userLogin, user);
	}
}

@@ -636,32 +636,107 @@
 LoginException;%0A
+import cz.metacentrum.perun.core.api.exceptions.PasswordStrengthException;%0A
 import cz.metace
@@ -789,32 +789,32 @@
 xistsException;%0A
-
 import cz.metace
@@ -1441,16 +1441,62 @@
 lass);%0A%0A
+%09protected final int passwordMinLength = 10;%0A%0A
 %09public 
@@ -1556,16 +1556,16 @@
 mespace%0A
-
 %09%09this.a
@@ -1605,16 +1605,620 @@
 z%22;%0A%09%7D%0A%0A
+%09@Override%0A%09public void checkPasswordStrength(PerunSession sess, String login, String password) throws PasswordStrengthException %7B%0A%0A%09%09super.checkPasswordStrength(sess, login, password);%0A%0A%09%09// we know it must be non-empty by super implementation%0A%09%09if (password.length() %3C passwordMinLength) %7B%0A%09%09%09log.warn(%22Password for %7B%7D:%7B%7D is too short. At least %7B%7D characters are required.%22, actualLoginNamespace, login, passwordMinLength);%0A%09%09%09throw new PasswordStrengthException(%22Password for %22 + actualLoginNamespace + %22:%22 + login + %22 is too short. At least %22+passwordMinLength+%22 characters are required.%22);%0A%09%09%7D%0A%0A%09%7D%0A%0A
 %09@Overri

set minimum password length for ics-muni-cz