Browse Source

fix #741

tags/v2.0.0-rc1
Shivaram Lingamneni 4 years ago
parent
commit
05cb80507f
4 changed files with 130 additions and 1 deletions
  1. 12
    1
      irc/accounts.go
  2. 7
    0
      irc/config.go
  3. 107
    0
      irc/hostserv.go
  4. 4
    0
      oragono.yaml

+ 12
- 1
irc/accounts.go View File

@@ -1129,6 +1129,7 @@ func (am *AccountManager) ModifyAccountSettings(account string, munger settingsM
1129 1129
 type VHostInfo struct {
1130 1130
 	ApprovedVHost   string
1131 1131
 	Enabled         bool
1132
+	Forbidden       bool
1132 1133
 	RequestedVHost  string
1133 1134
 	RejectedVHost   string
1134 1135
 	RejectionReason string
@@ -1207,6 +1208,16 @@ func (am *AccountManager) VHostSetEnabled(client *Client, enabled bool) (result
1207 1208
 	return am.performVHostChange(client.Account(), munger)
1208 1209
 }
1209 1210
 
1211
+func (am *AccountManager) VHostForbid(account string, forbid bool) (result VHostInfo, err error) {
1212
+	munger := func(input VHostInfo) (output VHostInfo, err error) {
1213
+		output = input
1214
+		output.Forbidden = forbid
1215
+		return
1216
+	}
1217
+
1218
+	return am.performVHostChange(account, munger)
1219
+}
1220
+
1210 1221
 func (am *AccountManager) performVHostChange(account string, munger vhostMunger) (result VHostInfo, err error) {
1211 1222
 	account, err = CasefoldName(account)
1212 1223
 	if err != nil || account == "" {
@@ -1322,7 +1333,7 @@ func (am *AccountManager) applyVHostInfo(client *Client, info VHostInfo) {
1322 1333
 	}
1323 1334
 
1324 1335
 	vhost := ""
1325
-	if info.Enabled {
1336
+	if info.Enabled && !info.Forbidden {
1326 1337
 		vhost = info.ApprovedVHost
1327 1338
 	}
1328 1339
 	oldNickmask := client.NickMaskString()

+ 7
- 0
irc/config.go View File

@@ -117,6 +117,7 @@ type VHostConfig struct {
117 117
 		Channel  string
118 118
 		Cooldown time.Duration
119 119
 	} `yaml:"user-requests"`
120
+	OfferList []string `yaml:"offer-list"`
120 121
 }
121 122
 
122 123
 type NickEnforcementMethod int
@@ -810,6 +811,12 @@ func LoadConfig(filename string) (config *Config, err error) {
810 811
 		config.Accounts.VHosts.ValidRegexp = defaultValidVhostRegex
811 812
 	}
812 813
 
814
+	for _, vhost := range config.Accounts.VHosts.OfferList {
815
+		if !config.Accounts.VHosts.ValidRegexp.MatchString(vhost) {
816
+			return nil, fmt.Errorf("invalid offered vhost: %s", vhost)
817
+		}
818
+	}
819
+
813 820
 	if !config.Accounts.LoginThrottling.Enabled {
814 821
 		config.Accounts.LoginThrottling.MaxAttempts = 0 // limit of 0 means disabled
815 822
 	}

+ 107
- 0
irc/hostserv.go View File

@@ -121,6 +121,51 @@ for the rejection.`,
121 121
 			maxParams:         2,
122 122
 			unsplitFinalParam: true,
123 123
 		},
124
+		"forbid": {
125
+			handler: hsForbidHandler,
126
+			help: `Syntax: $bFORBID <user>$b
127
+
128
+FORBID prevents a user from using any vhost, including ones on the offer list.`,
129
+			helpShort: `$bFORBID$b prevents a user from using vhosts.`,
130
+			capabs:    []string{"vhosts"},
131
+			enabled:   hostservEnabled,
132
+			minParams: 1,
133
+			maxParams: 1,
134
+		},
135
+		"permit": {
136
+			handler: hsForbidHandler,
137
+			help: `Syntax: $bPERMIT <user>$b
138
+
139
+PERMIT undoes FORBID, allowing the user to TAKE vhosts again.`,
140
+			helpShort: `$bPERMIT$b allows a user to use vhosts again.`,
141
+			capabs:    []string{"vhosts"},
142
+			enabled:   hostservEnabled,
143
+			minParams: 1,
144
+			maxParams: 1,
145
+		},
146
+		"offerlist": {
147
+			handler: hsOfferListHandler,
148
+			help: `Syntax: $bOFFERLIST$b
149
+
150
+OFFERLIST lists vhosts that can be chosen without requiring operator approval;
151
+to use one of the listed vhosts, take it with /HOSTSERV TAKE.`,
152
+			helpShort: `$bOFFERLIST$b lists vhosts that can be taken without operator approval.`,
153
+			enabled:   hostservEnabled,
154
+			minParams: 0,
155
+			maxParams: 0,
156
+		},
157
+		"take": {
158
+			handler: hsTakeHandler,
159
+			help: `Syntax: $bTAKE$b <vhost>
160
+
161
+TAKE sets your vhost to one of the vhosts in the server's offer list; to see
162
+the offered vhosts, use /HOSTSERV OFFERLIST.`,
163
+			helpShort:    `$bTAKE$b sets your vhost to one of the options from the offer list.`,
164
+			enabled:      hostservEnabled,
165
+			authRequired: true,
166
+			minParams:    1,
167
+			maxParams:    1,
168
+		},
124 169
 	}
125 170
 )
126 171
 
@@ -218,6 +263,11 @@ func hsStatusHandler(server *Server, client *Client, command string, params []st
218 263
 		return
219 264
 	}
220 265
 
266
+	if account.VHost.Forbidden {
267
+		hsNotice(rb, client.t("An administrator has denied you the ability to use vhosts"))
268
+		return
269
+	}
270
+
221 271
 	if account.VHost.ApprovedVHost != "" {
222 272
 		hsNotice(rb, fmt.Sprintf(client.t("Account %[1]s has vhost: %[2]s"), accountName, account.VHost.ApprovedVHost))
223 273
 		if !account.VHost.Enabled {
@@ -316,3 +366,60 @@ func hsRejectHandler(server *Server, client *Client, command string, params []st
316 366
 		}
317 367
 	}
318 368
 }
369
+
370
+func hsForbidHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
371
+	user := params[0]
372
+	forbidden := command == "forbid"
373
+
374
+	_, err := server.accounts.VHostForbid(user, forbidden)
375
+	if err == errAccountDoesNotExist {
376
+		hsNotice(rb, client.t("No such account"))
377
+	} else if err != nil {
378
+		hsNotice(rb, client.t("An error occurred"))
379
+	} else {
380
+		if forbidden {
381
+			hsNotice(rb, fmt.Sprintf(client.t("Successfully forbidden vhosts to user %s"), user))
382
+		} else {
383
+			hsNotice(rb, fmt.Sprintf(client.t("Successfully permitted vhosts for user %s"), user))
384
+		}
385
+	}
386
+}
387
+
388
+func hsOfferListHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
389
+	vhostConfig := server.Config().Accounts.VHosts
390
+	if len(vhostConfig.OfferList) == 0 {
391
+		if vhostConfig.UserRequests.Enabled {
392
+			hsNotice(rb, client.t("The server does not offer any vhosts (but you can request one with /HOSTSERV REQUEST)"))
393
+		} else {
394
+			hsNotice(rb, client.t("The server does not offer any vhosts)"))
395
+		}
396
+	} else {
397
+		hsNotice(rb, client.t("The following vhosts are available and can be chosen with /HOSTSERV TAKE:"))
398
+		for i, vhost := range vhostConfig.OfferList {
399
+			hsNotice(rb, fmt.Sprintf("%d. %s", i+1, vhost))
400
+		}
401
+	}
402
+}
403
+
404
+func hsTakeHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
405
+	vhost := params[0]
406
+	found := false
407
+	for _, offered := range server.Config().Accounts.VHosts.OfferList {
408
+		if offered == vhost {
409
+			found = true
410
+		}
411
+	}
412
+	if !found {
413
+		hsNotice(rb, client.t("That vhost isn't being offered by the server"))
414
+		return
415
+	}
416
+
417
+	_, err := server.accounts.VHostSet(client.Account(), vhost)
418
+	if err != nil {
419
+		hsNotice(rb, client.t("An error occurred"))
420
+	} else if vhost != "" {
421
+		hsNotice(rb, client.t("Successfully set vhost"))
422
+	} else {
423
+		hsNotice(rb, client.t("Successfully cleared vhost"))
424
+	}
425
+}

+ 4
- 0
oragono.yaml View File

@@ -380,6 +380,10 @@ accounts:
380 380
             # before they can request a new one.
381 381
             cooldown: 168h
382 382
 
383
+        # vhosts that users can take without approval, using `/HS TAKE`
384
+        offer-list:
385
+            #- "oragono.test"
386
+
383 387
 # channel options
384 388
 channels:
385 389
     # modes that are set when new channels are created

Loading…
Cancel
Save