cmd/faucet: use Twitter API instead of scraping webpage (#21850)
This PR adds support for using Twitter API to query the tweet and author details. There are two reasons behind this change: - Twitter will be deprecating the legacy website on 15th December. The current method is expected to stop working then. - More importantly, the current system uses Twitter handle for spam protection but the Twitter handle can be changed via automated calls. This allows bots to use the same tweet to withdraw funds infinite times as long as they keep changing their handle between every request. The Rinkeby as well as the Goerli faucet are being actively drained via this method. This PR changes the spam protection to be based on Twitter IDs instead of usernames. A user can not change their Twitter ID.
This commit is contained in:
@ -46,6 +46,7 @@ ENTRYPOINT [ \
|
||||
"--faucet.name", "{{.FaucetName}}", "--faucet.amount", "{{.FaucetAmount}}", "--faucet.minutes", "{{.FaucetMinutes}}", "--faucet.tiers", "{{.FaucetTiers}}", \
|
||||
"--account.json", "/account.json", "--account.pass", "/account.pass" \
|
||||
{{if .CaptchaToken}}, "--captcha.token", "{{.CaptchaToken}}", "--captcha.secret", "{{.CaptchaSecret}}"{{end}}{{if .NoAuth}}, "--noauth"{{end}} \
|
||||
{{if .TwitterToken}}, "--twitter.token", "{{.TwitterToken}}",
|
||||
]`
|
||||
|
||||
// faucetComposefile is the docker-compose.yml file required to deploy and maintain
|
||||
@ -71,6 +72,7 @@ services:
|
||||
- FAUCET_TIERS={{.FaucetTiers}}
|
||||
- CAPTCHA_TOKEN={{.CaptchaToken}}
|
||||
- CAPTCHA_SECRET={{.CaptchaSecret}}
|
||||
- TWITTER_TOKEN={{.TwitterToken}}
|
||||
- NO_AUTH={{.NoAuth}}{{if .VHost}}
|
||||
- VIRTUAL_HOST={{.VHost}}
|
||||
- VIRTUAL_PORT=8080{{end}}
|
||||
@ -103,6 +105,7 @@ func deployFaucet(client *sshClient, network string, bootnodes []string, config
|
||||
"FaucetMinutes": config.minutes,
|
||||
"FaucetTiers": config.tiers,
|
||||
"NoAuth": config.noauth,
|
||||
"TwitterToken": config.twitterToken,
|
||||
})
|
||||
files[filepath.Join(workdir, "Dockerfile")] = dockerfile.Bytes()
|
||||
|
||||
@ -120,6 +123,7 @@ func deployFaucet(client *sshClient, network string, bootnodes []string, config
|
||||
"FaucetMinutes": config.minutes,
|
||||
"FaucetTiers": config.tiers,
|
||||
"NoAuth": config.noauth,
|
||||
"TwitterToken": config.twitterToken,
|
||||
})
|
||||
files[filepath.Join(workdir, "docker-compose.yaml")] = composefile.Bytes()
|
||||
|
||||
@ -152,6 +156,7 @@ type faucetInfos struct {
|
||||
noauth bool
|
||||
captchaToken string
|
||||
captchaSecret string
|
||||
twitterToken string
|
||||
}
|
||||
|
||||
// Report converts the typed struct into a plain string->string map, containing
|
||||
@ -165,6 +170,7 @@ func (info *faucetInfos) Report() map[string]string {
|
||||
"Funding cooldown (base tier)": fmt.Sprintf("%d mins", info.minutes),
|
||||
"Funding tiers": strconv.Itoa(info.tiers),
|
||||
"Captha protection": fmt.Sprintf("%v", info.captchaToken != ""),
|
||||
"Using Twitter API": fmt.Sprintf("%v", info.twitterToken != ""),
|
||||
"Ethstats username": info.node.ethstats,
|
||||
}
|
||||
if info.noauth {
|
||||
@ -243,5 +249,6 @@ func checkFaucet(client *sshClient, network string) (*faucetInfos, error) {
|
||||
captchaToken: infos.envvars["CAPTCHA_TOKEN"],
|
||||
captchaSecret: infos.envvars["CAPTCHA_SECRET"],
|
||||
noauth: infos.envvars["NO_AUTH"] == "true",
|
||||
twitterToken: infos.envvars["TWITTER_TOKEN"],
|
||||
}, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user