whole buncha stuff

This commit is contained in:
tsmethurst 2021-03-15 23:05:24 +01:00
parent b48072fef6
commit 4e281f31b0
12 changed files with 151 additions and 24 deletions

2
go.mod
View file

@ -18,7 +18,7 @@ require (
github.com/tidwall/buntdb v1.2.0 // indirect
github.com/tidwall/pretty v1.1.0 // indirect
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/yaml.v2 v2.3.0
)

3
go.sum
View file

@ -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-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-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-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/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=

View file

@ -35,6 +35,10 @@ type Server interface {
Stop()
}
type AddsRoutes interface {
AddRoutes(s Server) error
}
type server struct {
APIGroup *gin.RouterGroup
logger *logrus.Logger

View file

@ -25,7 +25,6 @@
"github.com/go-fed/activity/pub"
"github.com/gotosocial/gotosocial/internal/config"
"github.com/gotosocial/oauth2/v4"
"github.com/sirupsen/logrus"
)
@ -40,11 +39,6 @@ type DB interface {
*/
pub.Database
/*
OAUTH2 DATABASE FUNCTIONS
*/
TokenStore() oauth2.TokenStore
/*
ANY ADDITIONAL DESIRED FUNCTIONS
*/

View file

@ -315,8 +315,9 @@ func (ps *postgresService) Stop(ctx context.Context) error {
func (ps *postgresService) CreateSchema(ctx context.Context) error {
models := []interface{}{
(*gtsmodel.GTSAccount)(nil),
(*gtsmodel.GTSStatus)(nil),
(*gtsmodel.Account)(nil),
(*gtsmodel.Status)(nil),
(*gtsmodel.User)(nil),
}
ps.log.Info("creating db schema")

20
internal/email/email.go Normal file
View 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

View file

@ -26,10 +26,10 @@
"time"
)
// GTSAccount represents a GoToSocial user account
type GTSAccount struct {
GTSAvatar
GTSHeader
// Account represents a GoToSocial user account
type Account struct {
Avatar
Header
URI string
URL string
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
@ -66,7 +66,7 @@ type GTSAccount struct {
SuspensionOrigin int
}
type GTSAvatar struct {
type Avatar struct {
AvatarFileName string
AvatarContentType string
AvatarFileSize int
@ -75,7 +75,7 @@ type GTSAvatar struct {
AvatarStorageSchemaVersion int
}
type GTSHeader struct {
type Header struct {
HeaderFileName string
HeaderContentType string
HeaderFileSize int

View file

@ -20,7 +20,7 @@
import "time"
type GTSStatus struct {
type Status struct {
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
URI string
URL string

65
internal/gtsmodel/user.go Normal file
View 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
}

View file

@ -19,19 +19,25 @@
package oauth
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/errors"
"github.com/gotosocial/oauth2/v4/manage"
"github.com/gotosocial/oauth2/v4/server"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/bcrypt"
)
type API struct {
manager *manage.Manager
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.MapTokenStorage(ts)
manager.MapClientStorage(cs)
@ -49,5 +55,41 @@ func New(ts oauth2.TokenStore, cs oauth2.ClientStore, log *logrus.Logger) *API {
return &API{
manager: manager,
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 := &gtsmodel.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
}

View file

@ -37,9 +37,9 @@ func NewPGClientStore(conn *pg.DB) oauth2.ClientStore {
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{
ID: id,
ID: clientID,
}
if err := pcs.conn.WithContext(ctx).Model(poc).Where("id = ?", poc.ID).Select(); err != nil {
return nil, err