mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 07:12:26 -05:00 
			
		
		
		
	email block checking for signups
This commit is contained in:
		
					parent
					
						
							
								88486b8447
							
						
					
				
			
			
				commit
				
					
						0a244be523
					
				
			
		
					 3 changed files with 30 additions and 12 deletions
				
			
		|  | @ -138,8 +138,11 @@ type DB interface { | |||
| 	// Returns an error if the username is already taken, or something went wrong in the db. | ||||
| 	IsUsernameAvailable(username string) error | ||||
| 
 | ||||
| 	// IsEmailAvailable checks whether a given email address for a user is available on our domain. | ||||
| 	// Returns an error if the email is already associated with an account, or something went wrong in the db. | ||||
| 	// IsEmailAvailable checks whether a given email address for a new account is available to be used on our domain. | ||||
| 	// Return an error if: | ||||
| 	// A) the email is already associated with an account | ||||
| 	// B) we block signups from this email domain | ||||
| 	// C) something went wrong in the db | ||||
| 	IsEmailAvailable(email string) error | ||||
| 
 | ||||
| 	/* | ||||
|  |  | |||
|  | @ -20,13 +20,11 @@ package model | |||
| 
 | ||||
| import "time" | ||||
| 
 | ||||
| // SignUpDomainBlock represents a domain that the server should automatically reject sign-up requests from. | ||||
| type SignUpDomainBlock struct { | ||||
| // EmailDomainBlock represents a domain that the server should automatically reject sign-up requests from. | ||||
| type EmailDomainBlock struct { | ||||
| 	// ID of this block in the database | ||||
| 	ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"` | ||||
| 	// Domain to block. If ANY PART of the candidate domain contains this string, it will be blocked. | ||||
| 	// For example: 'example.org' also blocks 'gts.example.org'. '.com' blocks *any* '.com' domains. | ||||
| 	// TODO: implement wildcards here | ||||
| 	// Email domain to block. Eg. 'gmail.com' or 'hotmail.com' | ||||
| 	Domain string `pg:",notnull"` | ||||
| 	// When was this block created | ||||
| 	CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"` | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ import ( | |||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/mail" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | @ -378,19 +379,35 @@ func (ps *postgresService) IsUsernameAvailable(username string) error { | |||
| 	if err := ps.conn.Model(&model.Account{}).Where("username = ?").Where("domain = ?", nil).Select(); err == nil { | ||||
| 		return fmt.Errorf("username %s already in use", username) | ||||
| 	} else if err != pg.ErrNoRows { | ||||
| 		return err | ||||
| 		return fmt.Errorf("db error: %s", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (ps *postgresService) IsEmailAvailable(email string) error { | ||||
| 	// if no error we fail because it means we found something | ||||
| 	// if error but it's not db.ErrorNoEntries then we fail | ||||
| 	// if err is ErrNoEntries we're good, we found nothing so continue | ||||
| 	// parse the domain from the email | ||||
| 	m, err := mail.ParseAddress(email) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error parsing email address %s: %s", email, err) | ||||
| 	} | ||||
| 	domain := strings.Split(m.Address, "@")[1] // domain will always be the second part after @ | ||||
| 
 | ||||
| 	// check if the email domain is blocked | ||||
| 	if err := ps.conn.Model(&model.EmailDomainBlock{}).Where("domain = ?", domain).Select(); err == nil { | ||||
| 		// fail because we found something | ||||
| 		return fmt.Errorf("email domain %s is blocked", domain) | ||||
| 	} else if err != pg.ErrNoRows { | ||||
| 		// fail because we got an unexpected error | ||||
| 		return fmt.Errorf("db error: %s", err) | ||||
| 	} | ||||
| 	 | ||||
| 	// check if this email is associated with an account already | ||||
| 	if err := ps.conn.Model(&model.Account{}).Where("email = ?", email).WhereOr("unconfirmed_email = ?", email).Select(); err == nil { | ||||
| 		// fail because we found something | ||||
| 		return fmt.Errorf("email %s already in use", email) | ||||
| 	} else if err != pg.ErrNoRows { | ||||
| 		return err | ||||
| 		// fail because we got an unexpected error | ||||
| 		return fmt.Errorf("db error: %s", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue