]> WPIA git - gigi.git/blobdiff - src/club/wpia/gigi/dbObjects/User.java
Merge changes If5eed01f,I88c94e39,If36f5b0a
[gigi.git] / src / club / wpia / gigi / dbObjects / User.java
index b65dbc5a027f5edee63c301b3dd12cd42f661957..834b6f68bc7a65148c0fd45c74afed35d30e6f20 100644 (file)
@@ -10,11 +10,14 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
+import java.util.TreeSet;
 
+import club.wpia.gigi.Gigi;
 import club.wpia.gigi.GigiApiException;
 import club.wpia.gigi.database.GigiPreparedStatement;
 import club.wpia.gigi.database.GigiResultSet;
 import club.wpia.gigi.dbObjects.CATS.CATSType;
+import club.wpia.gigi.dbObjects.Certificate.RevocationType;
 import club.wpia.gigi.dbObjects.Country.CountryCodeType;
 import club.wpia.gigi.dbObjects.Verification.VerificationType;
 import club.wpia.gigi.email.EmailProvider;
@@ -25,7 +28,6 @@ import club.wpia.gigi.util.CalendarUtil;
 import club.wpia.gigi.util.DayDate;
 import club.wpia.gigi.util.Notary;
 import club.wpia.gigi.util.PasswordHash;
-import club.wpia.gigi.util.PasswordStrengthChecker;
 import club.wpia.gigi.util.TimeConditions;
 
 /**
@@ -105,10 +107,7 @@ public class User extends CertificateOwner {
     }
 
     public User(String email, String password, DayDate dob, Locale locale, Country residenceCountry, NamePart... preferred) throws GigiApiException {
-        // Avoid storing information that obviously won't get through
-        if ( !EmailProvider.isValidMailAddress(email)) {
-            throw new IllegalArgumentException("Invalid email.");
-        }
+        super(validate(email));
 
         this.email = email;
         this.dob = dob;
@@ -128,6 +127,14 @@ public class User extends CertificateOwner {
         new EmailAddress(this, email, locale);
     }
 
+    private static Void validate(String email) {
+        // Avoid storing information that obviously won't get through
+        if ( !EmailProvider.isValidMailAddress(email)) {
+            throw new IllegalArgumentException("Invalid email.");
+        }
+        return null;
+    }
+
     public Name[] getNames() {
         try (GigiPreparedStatement gps = new GigiPreparedStatement("SELECT `id` FROM `names` WHERE `uid`=? AND `deleted` IS NULL", true)) {
             gps.setInt(1, getId());
@@ -167,7 +174,7 @@ public class User extends CertificateOwner {
                 throw new GigiApiException("Entered date of birth is below the restricted age requirements.");
             }
 
-            if (CalendarUtil.isOfAge(dob, User.MAXIMUM_PLAUSIBLE_AGE)) {
+            if (CalendarUtil.isYearsInFuture(dob.end(), User.MAXIMUM_PLAUSIBLE_AGE)) {
                 throw new GigiApiException("Entered date of birth exceeds the maximum age set in our policies. Please check your DoB is correct and contact support if the issue persists.");
             }
             this.dob = dob;
@@ -203,8 +210,18 @@ public class User extends CertificateOwner {
         setPassword(newPass);
     }
 
-    private void setPassword(String newPass) throws GigiApiException {
-        PasswordStrengthChecker.assertStrongPassword(newPass, getNames(), getEmail());
+    public void setPassword(String newPass) throws GigiApiException {
+        Name[] names = getNames();
+        TreeSet<String> nameParts = new TreeSet<>();
+        for (int i = 0; i < names.length; i++) {
+            for (NamePart string : names[i].getParts()) {
+                nameParts.add(string.getValue());
+            }
+        }
+        GigiApiException gaPassword = Gigi.getPasswordChecker().checkPassword(newPass, nameParts.toArray(new String[nameParts.size()]), getEmail());
+        if (gaPassword != null) {
+            throw gaPassword;
+        }
         try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE users SET `password`=? WHERE id=?")) {
             ps.setString(1, PasswordHash.hash(newPass));
             ps.setInt(2, getId());
@@ -226,6 +243,10 @@ public class User extends CertificateOwner {
             return false;
         }
 
+        if ( !Contract.hasSignedContract(this, Contract.ContractType.RA_AGENT_CONTRACT)) {
+            return false;
+        }
+
         return hasPassedCATS();
 
     }
@@ -318,6 +339,15 @@ public class User extends CertificateOwner {
         return false;
     }
 
+    public boolean isValidNameVerification(String name) {
+        for (Name n : getNames()) {
+            if (n.matches(name) && n.isValidVerification()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     public void updateDefaultEmail(EmailAddress newMail) throws GigiApiException {
         for (EmailAddress email : getEmails()) {
             if (email.getAddress().equals(newMail.getAddress())) {
@@ -344,16 +374,51 @@ public class User extends CertificateOwner {
             throw new GigiApiException("Can't delete user's default e-mail.");
         }
 
+        deleteEmailCerts(delMail, RevocationType.USER);
+    }
+
+    private void deleteEmailCerts(EmailAddress delMail, RevocationType rt) throws GigiApiException {
         for (EmailAddress email : getEmails()) {
             if (email.getId() == delMail.getId()) {
                 try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `emails` SET `deleted`=CURRENT_TIMESTAMP WHERE `id`=?")) {
                     ps.setInt(1, delMail.getId());
                     ps.execute();
                 }
+                LinkedList<Job> revokes = new LinkedList<Job>();
+                for (Certificate cert : fetchActiveEmailCertificates(delMail.getAddress())) {
+                    cert.revoke(RevocationType.USER).waitFor(Job.WAIT_MIN);
+                }
+                long start = System.currentTimeMillis();
+                for (Job job : revokes) {
+                    int toWait = (int) (60000 + start - System.currentTimeMillis());
+                    if (toWait > 0) {
+                        job.waitFor(toWait);
+                    } else {
+                        break; // canceled... waited too log
+                    }
+                }
                 return;
             }
+
         }
         throw new GigiApiException("Email not one of user's email addresses.");
+
+    }
+
+    public Certificate[] fetchActiveEmailCertificates(String email) {
+        try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT DISTINCT `certs`.`id` FROM `certs` INNER JOIN `subjectAlternativeNames` ON `subjectAlternativeNames`.`certId` = `certs`.`id` WHERE `contents`=?  AND `type`='email' AND `revoked` IS NULL AND `expire` > CURRENT_TIMESTAMP AND `memid`=?", true)) {
+            ps.setString(1, email);
+            ps.setInt(2, getId());
+            GigiResultSet rs = ps.executeQuery();
+            rs.last();
+            Certificate[] res = new Certificate[rs.getRow()];
+            rs.beforeFirst();
+            int i = 0;
+            while (rs.next()) {
+                res[i++] = Certificate.getById(rs.getInt(1));
+            }
+            return res;
+        }
     }
 
     public synchronized Verification[] getReceivedVerifications() {
@@ -437,6 +502,10 @@ public class User extends CertificateOwner {
 
     }
 
+    public synchronized String getInitials() {
+        return preferredName.toInitialsString();
+    }
+
     public boolean isInGroup(Group g) {
         return groups.contains(g);
     }
@@ -552,7 +621,7 @@ public class User extends CertificateOwner {
     }
 
     public String[] getTrainings() {
-        try (GigiPreparedStatement prep = new GigiPreparedStatement("SELECT `pass_date`, `type_text`, `language`, `version` FROM `cats_passed` LEFT JOIN `cats_type` ON `cats_type`.`id`=`cats_passed`.`variant_id`  WHERE `user_id`=? ORDER BY `pass_date` ASC")) {
+        try (GigiPreparedStatement prep = new GigiPreparedStatement("SELECT `pass_date`, `type_text`, `language`, `version` FROM `cats_passed` LEFT JOIN `cats_type` ON `cats_type`.`id`=`cats_passed`.`variant_id`  WHERE `user_id`=? ORDER BY `pass_date` DESC")) {
             prep.setInt(1, getId());
             GigiResultSet res = prep.executeQuery();
             List<String> entries = new LinkedList<String>();
@@ -660,4 +729,33 @@ public class User extends CertificateOwner {
             update.executeUpdate();
         }
     }
+
+    public boolean hasValidRAChallenge() {
+        return CATS.isInCatsLimit(getId(), CATSType.AGENT_CHALLENGE.getId());
+    }
+
+    public boolean hasValidSupportChallenge() {
+        return CATS.isInCatsLimit(getId(), CATSType.SUPPORT_DP_CHALLENGE_NAME.getId());
+    }
+
+    public boolean hasValidOrgAdminChallenge() {
+        return CATS.isInCatsLimit(getId(), CATSType.ORG_ADMIN_DP_CHALLENGE_NAME.getId());
+    }
+
+    public boolean hasValidOrgAgentChallenge() {
+        return CATS.isInCatsLimit(getId(), CATSType.ORG_AGENT_CHALLENGE.getId());
+    }
+
+    public boolean hasValidTTPAgentChallenge() {
+        return CATS.isInCatsLimit(getId(), CATSType.TTP_AGENT_CHALLENGE.getId());
+    }
+
+    public void writeUserLog(User actor, String type) throws GigiApiException {
+        try (GigiPreparedStatement prep = new GigiPreparedStatement("INSERT INTO `adminLog` SET uid=?, admin=?, type=?")) {
+            prep.setInt(1, actor.getId());
+            prep.setInt(2, getId());
+            prep.setString(3, type);
+            prep.executeUpdate();
+        }
+    }
 }