@@ -2,6 +2,7 @@ use std::{borrow::Cow, collections::HashSet};
22
33use eh2telegraph:: {
44 collector:: { e_hentai:: EHCollector , exhentai:: EXCollector , nhentai:: NHCollector } ,
5+ config:: { self , WhitelistConfig } , // Add whitelist
56 searcher:: {
67 f_hash:: FHashConvertor ,
78 saucenao:: { SaucenaoOutput , SaucenaoParsed , SaucenaoSearcher } ,
@@ -65,6 +66,7 @@ pub struct Handler<C> {
6566 pub searcher : SaucenaoSearcher ,
6667 pub convertor : FHashConvertor ,
6768 pub admins : HashSet < i64 > ,
69+ pub whitelist : HashSet < i64 > , // Add whitelist
6870
6971 single_flight : singleflight_async:: SingleFlight < String > ,
7072}
@@ -74,16 +76,59 @@ where
7476 C : KVStorage < String > + Send + Sync + ' static ,
7577{
7678 pub fn new ( synchronizer : Synchronizer < C > , admins : HashSet < i64 > ) -> Self {
79+ // Read whitelist
80+ let whitelist = match config:: parse :: < WhitelistConfig > ( "whitelist" )
81+ . ok ( )
82+ . and_then ( |x| x)
83+ {
84+ Some ( config) => {
85+ if config. enabled {
86+ // use ids in config
87+ config. ids . into_iter ( ) . collect ( )
88+ } else {
89+ // Allow all ppl to use
90+ HashSet :: from ( [ i64:: MIN ] )
91+ }
92+ }
93+ None => {
94+ // No white list, all ppl can use
95+ HashSet :: from ( [ i64:: MIN ] )
96+ }
97+ } ;
98+
7799 Self {
78100 synchronizer,
79101 searcher : SaucenaoSearcher :: new_from_config ( ) ,
80102 convertor : FHashConvertor :: new_from_config ( ) ,
81103 admins,
104+ whitelist,
82105
83106 single_flight : Default :: default ( ) ,
84107 }
85108 }
86109
110+ // Whitelist is allowed to use
111+ fn is_allowed ( & self , chat_id : i64 ) -> bool {
112+ if self . admins . contains ( & chat_id) {
113+ return true ;
114+ }
115+ if self . whitelist . contains ( & i64:: MIN ) {
116+ return true ;
117+ }
118+ self . whitelist . contains ( & chat_id)
119+ }
120+
121+ // Add unauthorized response
122+ async fn send_unauthorized ( & self , bot : & DefaultParseMode < Bot > , msg : & Message ) {
123+ // Only send in PM
124+ if msg. chat . is_private ( ) {
125+ let _ = bot
126+ . send_message ( msg. chat . id , escape ( "User not authorized!" ) )
127+ . reply_to_message_id ( msg. id )
128+ . await ;
129+ }
130+ }
131+
87132 /// Executed when a command comes in and parsed successfully.
88133 pub async fn respond_cmd (
89134 & ' static self ,
@@ -117,6 +162,11 @@ where
117162 . await ;
118163 }
119164 Command :: Sync ( url) => {
165+ // Add white list check
166+ if !self . is_allowed ( msg. chat . id . 0 ) {
167+ self . send_unauthorized ( & bot, & msg) . await ;
168+ return ControlFlow :: Break ( ( ) ) ;
169+ }
120170 if url. is_empty ( ) {
121171 let _ = bot
122172 . send_message ( msg. chat . id , escape ( "Usage: /sync url" ) )
@@ -170,6 +220,11 @@ where
170220 bot : DefaultParseMode < Bot > ,
171221 msg : Message ,
172222 ) -> ControlFlow < ( ) > {
223+ // Add white list check
224+ if !self . is_allowed ( msg. chat . id . 0 ) {
225+ self . send_unauthorized ( & bot, & msg) . await ;
226+ return ControlFlow :: Break ( ( ) ) ;
227+ }
173228 let maybe_link = {
174229 let entries = msg
175230 . entities ( )
@@ -220,6 +275,11 @@ where
220275 bot : DefaultParseMode < Bot > ,
221276 msg : Message ,
222277 ) -> ControlFlow < ( ) > {
278+ // Add white list check
279+ if !self . is_allowed ( msg. chat . id . 0 ) {
280+ self . send_unauthorized ( & bot, & msg) . await ;
281+ return ControlFlow :: Break ( ( ) ) ;
282+ }
223283 let caption_entities = msg. caption_entities ( ) ;
224284 let mut final_url = None ;
225285 for entry in caption_entities. map ( |x| x. iter ( ) ) . into_iter ( ) . flatten ( ) {
@@ -278,6 +338,11 @@ where
278338 bot : DefaultParseMode < Bot > ,
279339 msg : Message ,
280340 ) -> ControlFlow < ( ) > {
341+ // Add white list check
342+ if !self . is_allowed ( msg. chat . id . 0 ) {
343+ self . send_unauthorized ( & bot, & msg) . await ;
344+ return ControlFlow :: Break ( ( ) ) ;
345+ }
281346 let first_photo = match msg. photo ( ) . and_then ( |x| x. first ( ) ) {
282347 Some ( p) => p,
283348 None => {
0 commit comments