mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 23:02:25 -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. | 	// Returns an error if the username is already taken, or something went wrong in the db. | ||||||
| 	IsUsernameAvailable(username string) error | 	IsUsernameAvailable(username string) error | ||||||
| 
 | 
 | ||||||
| 	// IsEmailAvailable checks whether a given email address for a user is available on our domain. | 	// IsEmailAvailable checks whether a given email address for a new account is available to be used on our domain. | ||||||
| 	// Returns an error if the email is already associated with an account, or something went wrong in the db. | 	// 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 | 	IsEmailAvailable(email string) error | ||||||
| 
 | 
 | ||||||
| 	/* | 	/* | ||||||
|  |  | ||||||
|  | @ -20,13 +20,11 @@ package model | ||||||
| 
 | 
 | ||||||
| import "time" | import "time" | ||||||
| 
 | 
 | ||||||
| // SignUpDomainBlock represents a domain that the server should automatically reject sign-up requests from. | // EmailDomainBlock represents a domain that the server should automatically reject sign-up requests from. | ||||||
| type SignUpDomainBlock struct { | type EmailDomainBlock struct { | ||||||
| 	// ID of this block in the database | 	// ID of this block in the database | ||||||
| 	ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"` | 	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. | 	// Email domain to block. Eg. 'gmail.com' or 'hotmail.com' | ||||||
| 	// For example: 'example.org' also blocks 'gts.example.org'. '.com' blocks *any* '.com' domains. |  | ||||||
| 	// TODO: implement wildcards here |  | ||||||
| 	Domain string `pg:",notnull"` | 	Domain string `pg:",notnull"` | ||||||
| 	// When was this block created | 	// When was this block created | ||||||
| 	CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"` | 	CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"` | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"net/mail" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"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 { | 	if err := ps.conn.Model(&model.Account{}).Where("username = ?").Where("domain = ?", nil).Select(); err == nil { | ||||||
| 		return fmt.Errorf("username %s already in use", username) | 		return fmt.Errorf("username %s already in use", username) | ||||||
| 	} else if err != pg.ErrNoRows { | 	} else if err != pg.ErrNoRows { | ||||||
| 		return err | 		return fmt.Errorf("db error: %s", err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (ps *postgresService) IsEmailAvailable(email string) error { | func (ps *postgresService) IsEmailAvailable(email string) error { | ||||||
| 	// if no error we fail because it means we found something | 	// parse the domain from the email | ||||||
| 	// if error but it's not db.ErrorNoEntries then we fail | 	m, err := mail.ParseAddress(email) | ||||||
| 	// if err is ErrNoEntries we're good, we found nothing so continue | 	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 { | 	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) | 		return fmt.Errorf("email %s already in use", email) | ||||||
| 	} else if err != pg.ErrNoRows { | 	} else if err != pg.ErrNoRows { | ||||||
| 		return err | 		// fail because we got an unexpected error | ||||||
|  | 		return fmt.Errorf("db error: %s", err) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue