Skip to content

Commit a4aefb0

Browse files
committed
apply suggestions from code review
Signed-off-by: a1012112796 <[email protected]>
1 parent 99b67a2 commit a4aefb0

File tree

2 files changed

+331
-311
lines changed

2 files changed

+331
-311
lines changed

models/auth/oauth2.go

Lines changed: 0 additions & 311 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@ package auth
66
import (
77
"context"
88
"crypto/sha256"
9-
"crypto/subtle"
109
"encoding/base32"
1110
"encoding/base64"
12-
"encoding/hex"
1311
"errors"
1412
"fmt"
1513
"net"
@@ -694,312 +692,3 @@ func DeleteOAuth2RelictsByUserID(ctx context.Context, userID int64) error {
694692

695693
return nil
696694
}
697-
698-
type OAuth2Device struct {
699-
ID int64 `xorm:"pk autoincr"`
700-
DeviceCode string `xorm:"-"`
701-
DeviceCodeHash string `xorm:"UNIQUE"` // sha256 of device code
702-
DeviceCodeSalt string
703-
DeviceCodeID string `xorm:"INDEX"`
704-
UserCode string `xorm:"INDEX VARCHAR(9)"`
705-
Application *OAuth2Application `xorm:"-"`
706-
ApplicationID int64 `xorm:"INDEX"`
707-
Scope string `xorm:"TEXT"`
708-
GrantID int64
709-
CreatedUnix timeutil.TimeStamp `xorm:"created"`
710-
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
711-
ExpiredUnix timeutil.TimeStamp
712-
}
713-
714-
// TableName sets the table name to `oauth2_device`
715-
func (device *OAuth2Device) TableName() string {
716-
return "oauth2_device"
717-
}
718-
719-
func (device *OAuth2Device) LoadApplication(ctx context.Context) error {
720-
if device.Application != nil {
721-
return nil
722-
}
723-
724-
application := new(OAuth2Application)
725-
has, err := db.GetEngine(ctx).ID(device.ApplicationID).Get(application)
726-
if err != nil {
727-
return err
728-
}
729-
if !has {
730-
return &ErrOAuthApplicationNotFound{ID: device.ApplicationID}
731-
}
732-
733-
device.Application = application
734-
735-
return nil
736-
}
737-
738-
func generateUserCode() (string, error) {
739-
rBytes, err := util.CryptoRandomBytes(8)
740-
if err != nil {
741-
return "", err
742-
}
743-
letters := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
744-
code := make([]byte, 8)
745-
for i := range code {
746-
code[i] = letters[int(rBytes[i])%len(letters)]
747-
}
748-
return fmt.Sprintf("%s-%s", string(code[:4]), string(code[4:])), nil
749-
}
750-
751-
// CreateDevice generates a device for an user
752-
func (app *OAuth2Application) CreateDevice(ctx context.Context, scope string) (*OAuth2Device, error) {
753-
userCode, err := generateUserCode()
754-
if err != nil {
755-
return nil, err
756-
}
757-
758-
device := &OAuth2Device{
759-
ApplicationID: app.ID,
760-
UserCode: userCode,
761-
Scope: scope,
762-
ExpiredUnix: timeutil.TimeStampNow().Add(setting.OAuth2.DeviceFlowExpirationTime),
763-
}
764-
765-
salt, err := util.CryptoRandomString(10)
766-
if err != nil {
767-
return nil, err
768-
}
769-
code, err := util.CryptoRandomBytes(20)
770-
if err != nil {
771-
return nil, err
772-
}
773-
774-
device.DeviceCode = hex.EncodeToString(code)
775-
device.DeviceCodeSalt = salt
776-
device.DeviceCodeID = device.DeviceCode[len(device.DeviceCode)-8:]
777-
device.DeviceCodeHash = HashToken(device.DeviceCode, device.DeviceCodeSalt)
778-
779-
err = db.Insert(ctx, device)
780-
if err != nil {
781-
return nil, err
782-
}
783-
784-
return device, nil
785-
}
786-
787-
func (app *OAuth2Application) GetDeviceByDeviceCode(ctx context.Context, deviceCode string) (*OAuth2Device, error) {
788-
if len(deviceCode) != 40 {
789-
return nil, &ErrOAuth2DeviceNotFound{UserCode: deviceCode}
790-
}
791-
for _, x := range []byte(deviceCode) {
792-
if x < '0' || (x > '9' && x < 'a') || x > 'f' {
793-
return nil, &ErrOAuth2DeviceNotFound{UserCode: deviceCode}
794-
}
795-
}
796-
797-
deviceCodeID := deviceCode[len(deviceCode)-8:]
798-
var deviceList []OAuth2Device
799-
err := db.GetEngine(ctx).Table(&OAuth2Device{}).Where("device_code_id = ? AND application_id = ?", deviceCodeID, app.ID).Find(&deviceList)
800-
if err != nil {
801-
return nil, err
802-
} else if len(deviceList) == 0 {
803-
return nil, &ErrOAuth2DeviceNotFound{UserCode: deviceCode}
804-
}
805-
806-
for _, t := range deviceList {
807-
tempHash := HashToken(deviceCode, t.DeviceCodeSalt)
808-
if subtle.ConstantTimeCompare([]byte(t.DeviceCodeHash), []byte(tempHash)) == 1 {
809-
return &t, nil
810-
}
811-
}
812-
813-
return nil, &ErrOAuth2DeviceNotFound{UserCode: deviceCode}
814-
}
815-
816-
func (device *OAuth2Device) GetGrant(ctx context.Context) (*OAuth2DeviceGrant, error) {
817-
if device.GrantID <= 0 {
818-
return nil, fmt.Errorf("no grant found for device: %d", device.ID)
819-
}
820-
821-
grant := new(OAuth2DeviceGrant)
822-
_, err := db.GetEngine(ctx).ID(device.GrantID).Get(grant)
823-
824-
return grant, err
825-
}
826-
827-
type ErrOAuth2DeviceNotFound struct {
828-
UserCode string
829-
ID int64
830-
}
831-
832-
func (err *ErrOAuth2DeviceNotFound) Error() string {
833-
return fmt.Sprintf("oauth2 device not found: [user_code: %s. id: %d]", err.UserCode, err.ID)
834-
}
835-
836-
func IsErrOAuth2DeviceNotFound(err error) bool {
837-
_, ok := err.(*ErrOAuth2DeviceNotFound)
838-
return ok
839-
}
840-
841-
func GetDeviceByUserCode(ctx context.Context, userCode string) (*OAuth2Device, error) {
842-
device := new(OAuth2Device)
843-
844-
ok, err := db.GetEngine(ctx).Where("user_code = ? AND grant_id = ? AND expired_unix > ?",
845-
userCode, 0, timeutil.TimeStampNow()).Get(device)
846-
if err != nil {
847-
return nil, err
848-
}
849-
if !ok {
850-
return nil, &ErrOAuth2DeviceNotFound{UserCode: userCode}
851-
}
852-
853-
return device, nil
854-
}
855-
856-
func GetDeviceByID(ctx context.Context, id int64) (*OAuth2Device, error) {
857-
device := new(OAuth2Device)
858-
ok, err := db.GetEngine(ctx).ID(id).Get(device)
859-
if err != nil {
860-
return nil, err
861-
}
862-
if !ok {
863-
return nil, &ErrOAuth2DeviceNotFound{ID: id}
864-
}
865-
866-
return device, nil
867-
}
868-
869-
type OAuth2DeviceGrant struct {
870-
ID int64 `xorm:"pk autoincr"`
871-
UserID int64 `xorm:"INDEX"`
872-
Application *OAuth2Application `xorm:"-"`
873-
ApplicationID int64 `xorm:"INDEX"`
874-
DeviceID int64 `xorm:"INDEX"`
875-
Counter int64 `xorm:"NOT NULL DEFAULT 1"`
876-
UserCode string `xorm:"VARCHAR(9)"`
877-
Scope string `xorm:"TEXT"`
878-
Nonce string `xorm:"TEXT"`
879-
CreatedUnix timeutil.TimeStamp `xorm:"created"`
880-
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
881-
}
882-
883-
// TableName sets theOAuth2DeviceGrant table name to `oauth2_device_grant`
884-
func (grant *OAuth2DeviceGrant) TableName() string {
885-
return "oauth2_device_grant"
886-
}
887-
888-
func (device *OAuth2Device) CreateGrant(ctx context.Context, userID int64) error {
889-
return db.WithTx(ctx, func(ctx context.Context) error {
890-
grant := &OAuth2DeviceGrant{
891-
UserID: userID,
892-
DeviceID: device.ID,
893-
ApplicationID: device.ApplicationID,
894-
Scope: device.Scope,
895-
UserCode: device.UserCode,
896-
}
897-
err := db.Insert(ctx, grant)
898-
if err != nil {
899-
return err
900-
}
901-
902-
device.GrantID = grant.ID
903-
_, err = db.GetEngine(ctx).ID(device.ID).Cols("grant_id").Update(device)
904-
return err
905-
})
906-
}
907-
908-
// GetOAuth2GrantByID returns the grant with the given ID
909-
func GetOAuth2DeviceGrantByID(ctx context.Context, id int64) (grant *OAuth2DeviceGrant, err error) {
910-
grant = new(OAuth2DeviceGrant)
911-
if has, err := db.GetEngine(ctx).ID(id).Get(grant); err != nil {
912-
return nil, err
913-
} else if !has {
914-
return nil, nil
915-
}
916-
return grant, err
917-
}
918-
919-
func (grant *OAuth2DeviceGrant) IncreaseCounter(ctx context.Context) error {
920-
_, err := db.GetEngine(ctx).ID(grant.ID).Incr("counter").Update(new(OAuth2Grant))
921-
if err != nil {
922-
return err
923-
}
924-
updatedGrant, err := GetOAuth2DeviceGrantByID(ctx, grant.ID)
925-
if err != nil {
926-
return err
927-
}
928-
grant.Counter = updatedGrant.Counter
929-
return nil
930-
}
931-
932-
func (grant *OAuth2DeviceGrant) GetID() int64 {
933-
return -grant.ID
934-
}
935-
936-
func (grant *OAuth2DeviceGrant) GetCounter() int64 {
937-
return grant.Counter
938-
}
939-
940-
func (grant *OAuth2DeviceGrant) ScopeContains(scope string) bool {
941-
return slices.Contains(strings.Split(grant.Scope, " "), scope)
942-
}
943-
944-
func (grant *OAuth2DeviceGrant) GetApplicationID() int64 {
945-
return grant.ApplicationID
946-
}
947-
948-
func (grant *OAuth2DeviceGrant) GetUserID() int64 {
949-
return grant.UserID
950-
}
951-
952-
func (grant *OAuth2DeviceGrant) GetNonce() string {
953-
return grant.Nonce
954-
}
955-
956-
func (grant *OAuth2DeviceGrant) GetScope() string {
957-
return grant.Scope
958-
}
959-
960-
// GetOAuth2GrantsByUserID lists all grants of a certain user
961-
func GetOAuth2DeviceGrantsByUserID(ctx context.Context, uid int64) ([]*OAuth2DeviceGrant, error) {
962-
type joinedOAuth2DeviceGrant struct {
963-
Grant *OAuth2DeviceGrant `xorm:"extends"`
964-
Application *OAuth2Application `xorm:"extends"`
965-
}
966-
var results *xorm.Rows
967-
var err error
968-
if results, err = db.GetEngine(ctx).
969-
Table("oauth2_device_grant").
970-
Where("user_id = ?", uid).
971-
Join("INNER", "oauth2_application", "application_id = oauth2_application.id").
972-
Rows(new(joinedOAuth2DeviceGrant)); err != nil {
973-
return nil, err
974-
}
975-
defer results.Close()
976-
grants := make([]*OAuth2DeviceGrant, 0)
977-
for results.Next() {
978-
joinedGrant := new(joinedOAuth2DeviceGrant)
979-
if err := results.Scan(joinedGrant); err != nil {
980-
return nil, err
981-
}
982-
joinedGrant.Grant.Application = joinedGrant.Application
983-
grants = append(grants, joinedGrant.Grant)
984-
}
985-
return grants, nil
986-
}
987-
988-
// RevokeOAuth2Grant deletes the device grant with grantID and userID
989-
func RevokeOAuth2DeviceGrant(ctx context.Context, grantID, userID int64) error {
990-
if grantID <= 0 {
991-
return errors.New("invalid grant ID")
992-
}
993-
994-
return db.WithTx(ctx, func(ctx context.Context) error {
995-
_, err := db.GetEngine(ctx).Where(builder.Eq{"grant_id": grantID}).
996-
Delete(&OAuth2Device{})
997-
if err != nil {
998-
return err
999-
}
1000-
1001-
_, err = db.GetEngine(ctx).Where(builder.Eq{"id": grantID, "user_id": userID}).
1002-
Delete(&OAuth2DeviceGrant{})
1003-
return err
1004-
})
1005-
}

0 commit comments

Comments
 (0)