001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org> 002// 003// SPDX-License-Identifier: Apache-2.0 004 005package org.pgpainless.util.selection.userid; 006 007import java.util.ArrayList; 008import java.util.List; 009 010import org.bouncycastle.openpgp.PGPKeyRing; 011import org.pgpainless.PGPainless; 012 013import javax.annotation.Nonnull; 014 015public abstract class SelectUserId { 016 017 protected abstract boolean accept(String userId); 018 019 public List<String> selectUserIds(PGPKeyRing keyRing) { 020 List<String> userIds = PGPainless.inspectKeyRing(keyRing).getValidUserIds(); 021 return selectUserIds(userIds); 022 } 023 024 public List<String> selectUserIds(List<String> userIds) { 025 List<String> selected = new ArrayList<>(); 026 for (String userId : userIds) { 027 if (accept(userId)) { 028 selected.add(userId); 029 } 030 } 031 return selected; 032 } 033 034 public String firstMatch(PGPKeyRing keyRing) { 035 return firstMatch(selectUserIds(keyRing)); 036 } 037 038 public String firstMatch(List<String> userIds) { 039 for (String userId : userIds) { 040 if (accept(userId)) { 041 return userId; 042 } 043 } 044 return null; 045 } 046 047 public static SelectUserId containsSubstring(@Nonnull CharSequence query) { 048 return new SelectUserId() { 049 @Override 050 protected boolean accept(String userId) { 051 return userId.contains(query.toString()); 052 } 053 }; 054 } 055 056 public static SelectUserId exactMatch(@Nonnull CharSequence query) { 057 return new SelectUserId() { 058 @Override 059 protected boolean accept(String userId) { 060 return userId.equals(query.toString()); 061 } 062 }; 063 } 064 065 public static SelectUserId startsWith(@Nonnull CharSequence substring) { 066 String string = substring.toString(); 067 return new SelectUserId() { 068 @Override 069 protected boolean accept(String userId) { 070 return userId.startsWith(string); 071 } 072 }; 073 } 074 075 public static SelectUserId containsEmailAddress(@Nonnull CharSequence email) { 076 String string = email.toString(); 077 return containsSubstring(string.matches("^<.+>$") ? string : '<' + string + '>'); 078 } 079 080 public static SelectUserId validUserId(PGPKeyRing keyRing) { 081 return new SelectUserId() { 082 @Override 083 protected boolean accept(String userId) { 084 return PGPainless.inspectKeyRing(keyRing).isUserIdValid(userId); 085 } 086 }; 087 } 088 089 public static SelectUserId and(SelectUserId... strategies) { 090 return new SelectUserId() { 091 @Override 092 protected boolean accept(String userId) { 093 boolean accept = true; 094 for (SelectUserId strategy : strategies) { 095 accept &= strategy.accept(userId); 096 } 097 return accept; 098 } 099 }; 100 } 101 102 public static SelectUserId or(SelectUserId... strategies) { 103 return new SelectUserId() { 104 @Override 105 protected boolean accept(String userId) { 106 boolean accept = false; 107 for (SelectUserId strategy : strategies) { 108 accept |= strategy.accept(userId); 109 } 110 return accept; 111 } 112 }; 113 } 114 115 public static SelectUserId not(SelectUserId strategy) { 116 return new SelectUserId() { 117 @Override 118 protected boolean accept(String userId) { 119 return !strategy.accept(userId); 120 } 121 }; 122 } 123 124 public static SelectUserId byEmail(CharSequence email) { 125 return SelectUserId.or( 126 SelectUserId.exactMatch(email), 127 SelectUserId.containsEmailAddress(email) 128 ); 129 } 130}