|
7 | 7 | import java.util.*;
|
8 | 8 | import java.util.concurrent.*;
|
9 | 9 | import java.util.concurrent.locks.*;
|
| 10 | +import java.util.function.Predicate; |
| 11 | +import java.util.regex.*; |
10 | 12 | import java.nio.*;
|
11 | 13 | import java.nio.file.*;
|
12 | 14 | import java.nio.channels.*;
|
@@ -90,6 +92,47 @@ public static void init(Path mainFile, Path urlFile, Path cookieFile){
|
90 | 92 | Config.cookieFile = cookieFile;
|
91 | 93 | loadData();
|
92 | 94 | }
|
| 95 | + public static boolean deleteUnused(Set<String> users){ |
| 96 | + final Predicate<String> pred = new Predicate<>(){ |
| 97 | + @Override public boolean test(String o){ |
| 98 | + return !users.contains(o); |
| 99 | + } |
| 100 | + }; |
| 101 | + final HashSet<String> mfa = new HashSet<String>((int)Math.ceil(users.size()/0.75)); |
| 102 | + boolean changed = false; |
| 103 | + whitelistLock.writeLock().lock(); |
| 104 | + try{ |
| 105 | + changed|=whitelist.removeIf(pred); |
| 106 | + }finally{ |
| 107 | + whitelistLock.writeLock().unlock(); |
| 108 | + } |
| 109 | + mapLock.writeLock().lock(); |
| 110 | + try{ |
| 111 | + changed|=usernameEmailMappings.keySet().removeIf(pred); |
| 112 | + mfa.addAll(usernameEmailMappings.keySet()); |
| 113 | + }finally{ |
| 114 | + mapLock.writeLock().unlock(); |
| 115 | + } |
| 116 | + otpLock.writeLock().lock(); |
| 117 | + try{ |
| 118 | + changed|=usernameOTPMappings.keySet().removeIf(pred); |
| 119 | + mfa.addAll(usernameOTPMappings.keySet()); |
| 120 | + }finally{ |
| 121 | + otpLock.writeLock().unlock(); |
| 122 | + } |
| 123 | + cookieLock.writeLock().lock(); |
| 124 | + try{ |
| 125 | + changed|=cookieMappings.keySet().removeIf(new Predicate<String>(){ |
| 126 | + @Override public boolean test(String s){ |
| 127 | + final Matcher m = IPCookie.USERNAME_PATTERN.matcher(s); |
| 128 | + return !m.find() || !mfa.contains(m.group()); |
| 129 | + } |
| 130 | + }); |
| 131 | + }finally{ |
| 132 | + cookieLock.writeLock().unlock(); |
| 133 | + } |
| 134 | + return changed; |
| 135 | + } |
93 | 136 | private static <T> T get(CompletableFuture<T> x, long timeout) throws InterruptedException, ExecutionException, CancellationException {
|
94 | 137 | try{
|
95 | 138 | return x.get(timeout, TimeUnit.MILLISECONDS);
|
@@ -262,7 +305,7 @@ public static boolean submitToAPI(String user, String code, String ip, boolean c
|
262 | 305 | if (cache && result){
|
263 | 306 | final long cur = System.currentTimeMillis();
|
264 | 307 | if (apiResponseCache.size()>32){
|
265 |
| - apiResponseCache.values().removeIf(new java.util.function.Predicate<Long>(){ |
| 308 | + apiResponseCache.values().removeIf(new Predicate<Long>(){ |
266 | 309 | @Override public boolean test(Long o){
|
267 | 310 | return o<=cur;
|
268 | 311 | }
|
@@ -298,7 +341,7 @@ public static void insertCookie(String user, String ip){
|
298 | 341 | cookieLock.writeLock().lock();
|
299 | 342 | try{
|
300 | 343 | final long cur = System.currentTimeMillis();
|
301 |
| - cookieMappings.values().removeIf(new java.util.function.Predicate<IPCookie>(){ |
| 344 | + cookieMappings.values().removeIf(new Predicate<IPCookie>(){ |
302 | 345 | @Override public boolean test(IPCookie o){
|
303 | 346 | return o.expiry<=cur;
|
304 | 347 | }
|
@@ -326,7 +369,7 @@ public static boolean codeAlreadySubmitted(String user, String code){
|
326 | 369 | l = null;
|
327 | 370 | }
|
328 | 371 | if (submittedCodeCache.size()>32){
|
329 |
| - submittedCodeCache.values().removeIf(new java.util.function.Predicate<Long>(){ |
| 372 | + submittedCodeCache.values().removeIf(new Predicate<Long>(){ |
330 | 373 | @Override public boolean test(Long o){
|
331 | 374 | return o<=cur;
|
332 | 375 | }
|
@@ -359,7 +402,7 @@ public static boolean isRateLimited(String user){
|
359 | 402 | private static int getAttempts(String user){
|
360 | 403 | final long lim = System.currentTimeMillis()-90000L;
|
361 | 404 | final Container<Integer> count = new Container<>(0);
|
362 |
| - attempts.removeIf(new java.util.function.Predicate<Attempt>(){ |
| 405 | + attempts.removeIf(new Predicate<Attempt>(){ |
363 | 406 | @Override public boolean test(Attempt o) {
|
364 | 407 | if (o.time<lim){
|
365 | 408 | return true;
|
@@ -446,6 +489,39 @@ public static void printOTPs(StringBuilder sb){
|
446 | 489 | }
|
447 | 490 | sb.append(']');
|
448 | 491 | }
|
| 492 | + public static void checkCookies(Set<String> users){ |
| 493 | + final HashSet<String> set = new HashSet<>(Math.max((int)(users.size()/0.75), 16)); |
| 494 | + mapLock.readLock().lock(); |
| 495 | + try{ |
| 496 | + set.addAll(usernameEmailMappings.keySet()); |
| 497 | + }finally{ |
| 498 | + mapLock.readLock().unlock(); |
| 499 | + } |
| 500 | + set.removeAll(users); |
| 501 | + if (set.isEmpty()){ |
| 502 | + return; |
| 503 | + } |
| 504 | + otpLock.readLock().lock(); |
| 505 | + try{ |
| 506 | + set.removeAll(usernameOTPMappings.keySet()); |
| 507 | + }finally{ |
| 508 | + otpLock.readLock().unlock(); |
| 509 | + } |
| 510 | + if (set.isEmpty()){ |
| 511 | + return; |
| 512 | + } |
| 513 | + cookieLock.writeLock().lock(); |
| 514 | + try{ |
| 515 | + cookieMappings.keySet().removeIf(new Predicate<String>(){ |
| 516 | + @Override public boolean test(String s){ |
| 517 | + final Matcher m = IPCookie.USERNAME_PATTERN.matcher(s); |
| 518 | + return !m.find() || set.contains(m.group()); |
| 519 | + } |
| 520 | + }); |
| 521 | + }finally{ |
| 522 | + cookieLock.writeLock().unlock(); |
| 523 | + } |
| 524 | + } |
449 | 525 | public static void setEmails(Map<String,String> map){
|
450 | 526 | mapLock.writeLock().lock();
|
451 | 527 | try{
|
@@ -493,6 +569,19 @@ public static void setOTPs(Map<String,String> map){
|
493 | 569 | }
|
494 | 570 | }
|
495 | 571 | public static String setOTP(String username, String otp){
|
| 572 | + if (otp==null && !containsEmailFor(username)){ |
| 573 | + cookieLock.writeLock().lock(); |
| 574 | + try{ |
| 575 | + cookieMappings.keySet().removeIf(new Predicate<String>(){ |
| 576 | + @Override public boolean test(String s){ |
| 577 | + final Matcher m = IPCookie.USERNAME_PATTERN.matcher(s); |
| 578 | + return !m.find() || username.equalsIgnoreCase(m.group()); |
| 579 | + } |
| 580 | + }); |
| 581 | + }finally{ |
| 582 | + cookieLock.writeLock().unlock(); |
| 583 | + } |
| 584 | + } |
496 | 585 | otpLock.writeLock().lock();
|
497 | 586 | try{
|
498 | 587 | if (otp==null){
|
|
0 commit comments