@@ -16,21 +16,17 @@ limitations under the License.
1616
1717import { Mjolnir } from "../Mjolnir" ;
1818import PolicyList from "../models/PolicyList" ;
19- import { extractRequestError , LogLevel , LogService , MatrixGlob , RichReply } from "matrix-bot-sdk" ;
19+ import { extractRequestError , LogLevel , LogService , MatrixGlob } from "matrix-bot-sdk" ;
2020import { RULE_ROOM , RULE_SERVER , RULE_USER , USER_RULE_TYPES } from "../models/ListRule" ;
2121import { DEFAULT_LIST_EVENT_TYPE } from "./SetDefaultBanListCommand" ;
2222import { defineApplicationCommand } from "./ApplicationCommand" ;
2323import { defineMatrixInterfaceCommand } from "./MatrixInterfaceCommand" ;
24+ import { ValidationError , ValidationResult } from "./Validation" ;
2425
25- interface Arguments {
26- list : PolicyList | null ;
27- entity : string ;
28- ruleType : string | null ;
29- reason : string ;
30- }
26+ type Arguments = Parameters < ( mjolnir : Mjolnir , list : PolicyList , ruleType : string , entity : string , reason : string ) => void > ;
3127
3228// Exported for tests
33- export async function parseArguments ( roomId : string , event : any , mjolnir : Mjolnir , parts : string [ ] ) : Promise < Arguments | null > {
29+ export async function parseArguments ( mjolnir : Mjolnir , roomId : string , event : any , parts : string [ ] ) : Promise < ValidationResult < Arguments , ValidationError > > {
3430 let defaultShortcode : string | null = null ;
3531 try {
3632 const data : { shortcode : string } = await mjolnir . client . getAccountData ( DEFAULT_LIST_EVENT_TYPE ) ;
@@ -42,10 +38,19 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
4238 // Assume no default.
4339 }
4440
41+ const findList = ( mjolnir : Mjolnir , shortcode : string ) : ValidationResult < PolicyList , ValidationError > => {
42+ const foundList = mjolnir . lists . find ( b => b . listShortcode . toLowerCase ( ) === shortcode . toLowerCase ( ) ) ;
43+ if ( foundList !== undefined ) {
44+ return ValidationResult . Ok ( foundList ) ;
45+ } else {
46+ return ValidationResult . Err ( ValidationError . makeValidationError ( 'shortcode not found' , `A list with the shourtcode ${ shortcode } could not be found.` ) ) ;
47+ }
48+ }
49+
4550 let argumentIndex = 2 ;
4651 let ruleType : string | null = null ;
4752 let entity : string | null = null ;
48- let list : PolicyList | null = null ;
53+ let list : ValidationResult < PolicyList , ValidationError > | null = null ;
4954 let force = false ;
5055 while ( argumentIndex < 7 && argumentIndex < parts . length ) {
5156 const arg = parts [ argumentIndex ++ ] ;
@@ -61,10 +66,7 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
6166 else if ( arg . startsWith ( "!" ) && ! ruleType ) ruleType = RULE_ROOM ;
6267 else if ( ! ruleType ) ruleType = RULE_SERVER ;
6368 } else if ( ! list ) {
64- const foundList = mjolnir . lists . find ( b => b . listShortcode . toLowerCase ( ) === arg . toLowerCase ( ) ) ;
65- if ( foundList !== undefined ) {
66- list = foundList ;
67- }
69+ list = findList ( mjolnir , arg . toLocaleLowerCase ( ) ) ;
6870 }
6971
7072 if ( entity ) break ;
@@ -88,47 +90,55 @@ export async function parseArguments(roomId: string, event: any, mjolnir: Mjolni
8890 }
8991
9092 if ( ! list ) {
91- list = mjolnir . lists . find ( b => b . listShortcode . toLowerCase ( ) === defaultShortcode ) || null ;
92- }
93-
94- let replyMessage : string | null = null ;
95- if ( ! list ) replyMessage = "No ban list matching that shortcode was found" ;
96- else if ( ! ruleType ) replyMessage = "Please specify the type as either 'user', 'room', or 'server'" ;
97- else if ( ! entity ) replyMessage = "No entity found" ;
98-
99- if ( mjolnir . config . commands . confirmWildcardBan && / [ * ? ] / . test ( entity ) && ! force ) {
100- replyMessage = "Wildcard bans require an additional `--force` argument to confirm" ;
93+ if ( defaultShortcode ) {
94+ list = await findList ( mjolnir , defaultShortcode ) ;
95+ if ( list . isErr ( ) ) {
96+ return ValidationResult . Err ( ValidationError . makeValidationError (
97+ "shortcode not found" ,
98+ `A shortcode was not provided for this command, and a list couldn't be found with the default shortcode ${ defaultShortcode } ` ) )
99+ }
100+ } else {
101+ // FIXME: should be turned into a utility function to find the default list.
102+ // and in general, why is there a default shortcode instead of a default list?
103+ return ValidationResult . Err ( ValidationError . makeValidationError (
104+ "no default shortcode" ,
105+ `A shortcode was not provided for this command, and a default shortcode was not set either.`
106+ ) )
107+ }
101108 }
102109
103- if ( replyMessage ) {
104- const reply = RichReply . createFor ( roomId , event , replyMessage , replyMessage ) ;
105- reply [ "msgtype" ] = "m.notice" ;
106- await mjolnir . client . sendMessage ( roomId , reply ) ;
107- return null ;
110+ if ( list . isErr ( ) ) {
111+ return ValidationResult . Err ( list . err ) ;
112+ } else if ( ! ruleType ) {
113+ return ValidationResult . Err (
114+ ValidationError . makeValidationError ( 'uknown rule type' , "Please specify the type as either 'user', 'room', or 'server'" )
115+ ) ;
116+ } else if ( ! entity ) {
117+ return ValidationResult . Err (
118+ ValidationError . makeValidationError ( 'no entity' , "No entity was able to be parsed from this command" )
119+ ) ;
120+ } else if ( mjolnir . config . commands . confirmWildcardBan && / [ * ? ] / . test ( entity ) && ! force ) {
121+ return ValidationResult . Err (
122+ ValidationError . makeValidationError ( "wildcard required" , "Wildcard bans require an additional `--force` argument to confirm" )
123+ ) ;
108124 }
109125
110- return {
111- list ,
112- entity ,
126+ return ValidationResult . Ok ( [
127+ mjolnir ,
128+ list . ok ,
113129 ruleType ,
114- reason : parts . splice ( argumentIndex ) . join ( " " ) . trim ( ) ,
115- } ;
130+ entity ,
131+ parts . splice ( argumentIndex ) . join ( " " ) . trim ( ) ,
132+ ] ) ;
116133}
117134
118- const BAN_COMMAND = defineApplicationCommand ( [ ] , async ( list : PolicyList , ruleType : string , entity : string , reason : string ) : Promise < void > => {
135+ const BAN_COMMAND = defineApplicationCommand ( [ ] , async ( mjonlir : Mjolnir , list : PolicyList , ruleType : string , entity : string , reason : string ) : Promise < void > => {
119136 await list . banEntity ( ruleType , entity , reason ) ;
120137} ) ;
121138
122139// !mjolnir ban <shortcode> <user|server|room> <glob> [reason] [--force]
123140defineMatrixInterfaceCommand ( [ "ban" ] ,
124- async function ( mjolnir : Mjolnir , roomId : string , event : any , parts : string [ ] ) : Promise < [ PolicyList , string , string , string ] > {
125- const bits = await parseArguments ( roomId , event , mjolnir , parts ) ;
126- if ( bits === null ) {
127- // FIXME
128- throw new Error ( "Couldn't parse arguments FIXME - parser needs to be rewritten to reject nulls" ) ;
129- }
130- return [ bits . list ! , bits . ruleType ! , bits . entity ! , bits . reason ! ] ;
131- } ,
141+ parseArguments ,
132142 BAN_COMMAND ,
133143 async function ( mjolnir : Mjolnir , commandRoomId : string , event : any , result : void ) {
134144 await mjolnir . client . unstableApis . addReactionToEvent ( commandRoomId , event [ 'event_id' ] , '✅' ) ;
@@ -180,13 +190,7 @@ const UNBAN_COMMAND = defineApplicationCommand([], async (mjolnir: Mjolnir, list
180190
181191// !mjolnir unban <shortcode> <user|server|room> <glob> [apply:t/f]
182192defineMatrixInterfaceCommand ( [ "unban" ] ,
183- async function ( mjolnir : Mjolnir , roomId : string , event : any , parts : string [ ] ) : Promise < [ Mjolnir , PolicyList , string , string , string ] > {
184- const bits = await parseArguments ( roomId , event , mjolnir , parts ) ;
185- if ( bits === null ) {
186- throw new Error ( "Couldn't parse arguments FIXME" ) ;
187- }
188- return [ mjolnir , bits . list ! , bits . ruleType ! , bits . entity ! , bits . reason ! ] ;
189- } ,
193+ parseArguments ,
190194 UNBAN_COMMAND ,
191195 async function ( mjolnir : Mjolnir , commandRoomId : string , event : any , result : void ) {
192196 await mjolnir . client . unstableApis . addReactionToEvent ( commandRoomId , event [ 'event_id' ] , '✅' ) ;
0 commit comments