mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 12:52:25 -05:00 
			
		
		
		
	whole buncha stuff
This commit is contained in:
		
					parent
					
						
							
								b48072fef6
							
						
					
				
			
			
				commit
				
					
						4e281f31b0
					
				
			
		
					 12 changed files with 151 additions and 24 deletions
				
			
		
							
								
								
									
										2
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -18,7 +18,7 @@ require ( | ||||||
| 	github.com/tidwall/buntdb v1.2.0 // indirect | 	github.com/tidwall/buntdb v1.2.0 // indirect | ||||||
| 	github.com/tidwall/pretty v1.1.0 // indirect | 	github.com/tidwall/pretty v1.1.0 // indirect | ||||||
| 	github.com/urfave/cli/v2 v2.3.0 | 	github.com/urfave/cli/v2 v2.3.0 | ||||||
| 	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect | 	golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b | ||||||
| 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | ||||||
| 	gopkg.in/yaml.v2 v2.3.0 | 	gopkg.in/yaml.v2 v2.3.0 | ||||||
| ) | ) | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -240,8 +240,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk | ||||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= |  | ||||||
| golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= | golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= | ||||||
|  | golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b h1:wSOdpTq0/eI46Ez/LkDwIsAKA71YP2SRKBODiRWM0as= | ||||||
|  | golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | ||||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||||
| golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | ||||||
|  |  | ||||||
|  | @ -35,6 +35,10 @@ type Server interface { | ||||||
| 	Stop() | 	Stop() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type AddsRoutes interface { | ||||||
|  | 	AddRoutes(s Server) error | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type server struct { | type server struct { | ||||||
| 	APIGroup *gin.RouterGroup | 	APIGroup *gin.RouterGroup | ||||||
| 	logger   *logrus.Logger | 	logger   *logrus.Logger | ||||||
|  |  | ||||||
|  | @ -25,7 +25,6 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-fed/activity/pub" | 	"github.com/go-fed/activity/pub" | ||||||
| 	"github.com/gotosocial/gotosocial/internal/config" | 	"github.com/gotosocial/gotosocial/internal/config" | ||||||
| 	"github.com/gotosocial/oauth2/v4" |  | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -40,11 +39,6 @@ type DB interface { | ||||||
| 	*/ | 	*/ | ||||||
| 	pub.Database | 	pub.Database | ||||||
| 
 | 
 | ||||||
| 	/* |  | ||||||
| 		OAUTH2 DATABASE FUNCTIONS |  | ||||||
| 	*/ |  | ||||||
| 	TokenStore() oauth2.TokenStore |  | ||||||
| 
 |  | ||||||
| 	/* | 	/* | ||||||
| 		ANY ADDITIONAL DESIRED FUNCTIONS | 		ANY ADDITIONAL DESIRED FUNCTIONS | ||||||
| 	*/ | 	*/ | ||||||
|  |  | ||||||
|  | @ -315,8 +315,9 @@ func (ps *postgresService) Stop(ctx context.Context) error { | ||||||
| 
 | 
 | ||||||
| func (ps *postgresService) CreateSchema(ctx context.Context) error { | func (ps *postgresService) CreateSchema(ctx context.Context) error { | ||||||
| 	models := []interface{}{ | 	models := []interface{}{ | ||||||
| 		(*gtsmodel.GTSAccount)(nil), | 		(*gtsmodel.Account)(nil), | ||||||
| 		(*gtsmodel.GTSStatus)(nil), | 		(*gtsmodel.Status)(nil), | ||||||
|  | 		(*gtsmodel.User)(nil), | ||||||
| 	} | 	} | ||||||
| 	ps.log.Info("creating db schema") | 	ps.log.Info("creating db schema") | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								internal/email/email.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								internal/email/email.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | // package email provides a service for interacting with an SMTP server | ||||||
|  | package email | ||||||
|  | @ -26,10 +26,10 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // GTSAccount represents a GoToSocial user account | // Account represents a GoToSocial user account | ||||||
| type GTSAccount struct { | type Account struct { | ||||||
| 	GTSAvatar | 	Avatar | ||||||
| 	GTSHeader | 	Header | ||||||
| 	URI                   string | 	URI                   string | ||||||
| 	URL                   string | 	URL                   string | ||||||
| 	ID                    string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"` | 	ID                    string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"` | ||||||
|  | @ -66,7 +66,7 @@ type GTSAccount struct { | ||||||
| 	SuspensionOrigin      int | 	SuspensionOrigin      int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type GTSAvatar struct { | type Avatar struct { | ||||||
| 	AvatarFileName             string | 	AvatarFileName             string | ||||||
| 	AvatarContentType          string | 	AvatarContentType          string | ||||||
| 	AvatarFileSize             int | 	AvatarFileSize             int | ||||||
|  | @ -75,7 +75,7 @@ type GTSAvatar struct { | ||||||
| 	AvatarStorageSchemaVersion int | 	AvatarStorageSchemaVersion int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type GTSHeader struct { | type Header struct { | ||||||
| 	HeaderFileName             string | 	HeaderFileName             string | ||||||
| 	HeaderContentType          string | 	HeaderContentType          string | ||||||
| 	HeaderFileSize             int | 	HeaderFileSize             int | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ package gtsmodel | ||||||
| 
 | 
 | ||||||
| import "time" | import "time" | ||||||
| 
 | 
 | ||||||
| type GTSStatus struct { | type Status struct { | ||||||
| 	ID             string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"` | 	ID             string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"` | ||||||
| 	URI            string | 	URI            string | ||||||
| 	URL            string | 	URL            string | ||||||
|  |  | ||||||
							
								
								
									
										65
									
								
								internal/gtsmodel/user.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								internal/gtsmodel/user.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package gtsmodel | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type User struct { | ||||||
|  | 	ID                     string    `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"` | ||||||
|  | 	Email                  string    `pg:",notnull"` | ||||||
|  | 	CreatedAt              time.Time `pg:"type:timestamp,notnull"` | ||||||
|  | 	UpdatedAt              time.Time `pg:"type:timestamp,notnull"` | ||||||
|  | 	EncryptedPassword      string    `pg:",notnull"` | ||||||
|  | 	ResetPasswordToken     string | ||||||
|  | 	ResetPasswordSentAt    time.Time `pg:"type:timestamp"` | ||||||
|  | 	SignInCount            int | ||||||
|  | 	CurrentSignInAt        time.Time `pg:"type:timestamp"` | ||||||
|  | 	LastSignInAt           time.Time `pg:"type:timestamp"` | ||||||
|  | 	CurrentSignInIP        net.IP | ||||||
|  | 	LastSignInIP           net.IP | ||||||
|  | 	Admin                  bool | ||||||
|  | 	ConfirmationToken      string | ||||||
|  | 	ConfirmedAt            time.Time `pg:"type:timestamp"` | ||||||
|  | 	ConfirmationSentAt     time.Time `pg:"type:timestamp"` | ||||||
|  | 	UnconfirmedEmail       string | ||||||
|  | 	Locale                 string | ||||||
|  | 	EncryptedOTPSecret     string | ||||||
|  | 	EncryptedOTPSecretIv   string | ||||||
|  | 	EncryptedOTPSecretSalt string | ||||||
|  | 	ConsumedTimestamp      int | ||||||
|  | 	OTPRequiredForLogin    bool | ||||||
|  | 	LastEmailedAt          time.Time `pg:"type:timestamp"` | ||||||
|  | 	OTPBackupCodes         []string | ||||||
|  | 	FilteredLanguages      []string | ||||||
|  | 	AccountID              string `pg:",notnull"` | ||||||
|  | 	Disabled               bool | ||||||
|  | 	Moderator              bool | ||||||
|  | 	InviteID               string | ||||||
|  | 	RememberToken          string | ||||||
|  | 	ChosenLanguages        []string | ||||||
|  | 	CreatedByApplicationID string | ||||||
|  | 	Approved               bool | ||||||
|  | 	SignInToken            string | ||||||
|  | 	SignInTokenSentAt      time.Time `pg:"type:timestamp"` | ||||||
|  | 	WebauthnID             string | ||||||
|  | 	SignUpIP               net.IP | ||||||
|  | } | ||||||
|  | @ -19,19 +19,25 @@ | ||||||
| package oauth | package oauth | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"github.com/go-pg/pg/v10" | ||||||
|  | 	"github.com/gotosocial/gotosocial/internal/api" | ||||||
|  | 	"github.com/gotosocial/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/gotosocial/oauth2/v4" | 	"github.com/gotosocial/oauth2/v4" | ||||||
| 	"github.com/gotosocial/oauth2/v4/errors" | 	"github.com/gotosocial/oauth2/v4/errors" | ||||||
| 	"github.com/gotosocial/oauth2/v4/manage" | 	"github.com/gotosocial/oauth2/v4/manage" | ||||||
| 	"github.com/gotosocial/oauth2/v4/server" | 	"github.com/gotosocial/oauth2/v4/server" | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
|  | 	"golang.org/x/crypto/bcrypt" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type API struct { | type API struct { | ||||||
| 	manager *manage.Manager | 	manager *manage.Manager | ||||||
| 	server  *server.Server | 	server  *server.Server | ||||||
|  | 	conn    *pg.DB | ||||||
|  | 	log     *logrus.Logger | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func New(ts oauth2.TokenStore, cs oauth2.ClientStore, log *logrus.Logger) *API { | func New(ts oauth2.TokenStore, cs oauth2.ClientStore, conn *pg.DB, log *logrus.Logger) *API { | ||||||
| 	manager := manage.NewDefaultManager() | 	manager := manage.NewDefaultManager() | ||||||
| 	manager.MapTokenStorage(ts) | 	manager.MapTokenStorage(ts) | ||||||
| 	manager.MapClientStorage(cs) | 	manager.MapClientStorage(cs) | ||||||
|  | @ -49,5 +55,41 @@ func New(ts oauth2.TokenStore, cs oauth2.ClientStore, log *logrus.Logger) *API { | ||||||
| 	return &API{ | 	return &API{ | ||||||
| 		manager: manager, | 		manager: manager, | ||||||
| 		server:  srv, | 		server:  srv, | ||||||
|  | 		conn:    conn, | ||||||
|  | 		log:     log, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (a *API) AddRoutes(s api.Server) error { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func incorrectPassword() (string, error) { | ||||||
|  | 	return "", errors.New("password/email combination was incorrect") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (a *API) PasswordAuthorizationHandler(email string, password string) (userid string, err error) { | ||||||
|  | 	// first we select the user from the database based on email address, bail if no user found for that email | ||||||
|  | 	gtsUser := >smodel.User{} | ||||||
|  | 	if err := a.conn.Model(gtsUser).Where("email = ?", email).Select(); err != nil { | ||||||
|  | 		a.log.Debugf("user %s was not retrievable from db during oauth authorization attempt: %s", email, err) | ||||||
|  | 		return incorrectPassword() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// make sure a password is actually set and bail if not | ||||||
|  | 	if gtsUser.EncryptedPassword == "" { | ||||||
|  | 		a.log.Warnf("encrypted password for user %s was empty for some reason", gtsUser.Email) | ||||||
|  | 		return incorrectPassword() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// compare the provided password with the encrypted one from the db, bail if they don't match | ||||||
|  | 	if err := bcrypt.CompareHashAndPassword([]byte(gtsUser.EncryptedPassword), []byte(password)); err != nil { | ||||||
|  | 		a.log.Debugf("password hash didn't match for user %s during login attempt: %s", gtsUser.Email, err) | ||||||
|  | 		return incorrectPassword() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// If we've made it this far the email/password is correct so we need the oauth client-id of the user | ||||||
|  | 	// This is, conveniently, the same as the user ID, so we can just return it. | ||||||
|  | 	userid = gtsUser.ID | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -37,9 +37,9 @@ func NewPGClientStore(conn *pg.DB) oauth2.ClientStore { | ||||||
| 	return pts | 	return pts | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (pcs *pgClientStore) GetByID(ctx context.Context, id string) (oauth2.ClientInfo, error) { | func (pcs *pgClientStore) GetByID(ctx context.Context, clientID string) (oauth2.ClientInfo, error) { | ||||||
| 	poc := &oauthClient{ | 	poc := &oauthClient{ | ||||||
| 		ID: id, | 		ID: clientID, | ||||||
| 	} | 	} | ||||||
| 	if err := pcs.conn.WithContext(ctx).Model(poc).Where("id = ?", poc.ID).Select(); err != nil { | 	if err := pcs.conn.WithContext(ctx).Model(poc).Where("id = ?", poc.ID).Select(); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue