code.gitea.io/gitea@v1.21.7/models/user/openid.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package user 5 6 import ( 7 "context" 8 "fmt" 9 10 "code.gitea.io/gitea/models/db" 11 "code.gitea.io/gitea/modules/util" 12 ) 13 14 // ErrOpenIDNotExist openid is not known 15 var ErrOpenIDNotExist = util.NewNotExistErrorf("OpenID is unknown") 16 17 // UserOpenID is the list of all OpenID identities of a user. 18 // Since this is a middle table, name it OpenID is not suitable, so we ignore the lint here 19 type UserOpenID struct { //revive:disable-line:exported 20 ID int64 `xorm:"pk autoincr"` 21 UID int64 `xorm:"INDEX NOT NULL"` 22 URI string `xorm:"UNIQUE NOT NULL"` 23 Show bool `xorm:"DEFAULT false"` 24 } 25 26 func init() { 27 db.RegisterModel(new(UserOpenID)) 28 } 29 30 // GetUserOpenIDs returns all openid addresses that belongs to given user. 31 func GetUserOpenIDs(ctx context.Context, uid int64) ([]*UserOpenID, error) { 32 openids := make([]*UserOpenID, 0, 5) 33 if err := db.GetEngine(ctx). 34 Where("uid=?", uid). 35 Asc("id"). 36 Find(&openids); err != nil { 37 return nil, err 38 } 39 40 return openids, nil 41 } 42 43 // isOpenIDUsed returns true if the openid has been used. 44 func isOpenIDUsed(ctx context.Context, uri string) (bool, error) { 45 if len(uri) == 0 { 46 return true, nil 47 } 48 49 return db.GetEngine(ctx).Get(&UserOpenID{URI: uri}) 50 } 51 52 // ErrOpenIDAlreadyUsed represents a "OpenIDAlreadyUsed" kind of error. 53 type ErrOpenIDAlreadyUsed struct { 54 OpenID string 55 } 56 57 // IsErrOpenIDAlreadyUsed checks if an error is a ErrOpenIDAlreadyUsed. 58 func IsErrOpenIDAlreadyUsed(err error) bool { 59 _, ok := err.(ErrOpenIDAlreadyUsed) 60 return ok 61 } 62 63 func (err ErrOpenIDAlreadyUsed) Error() string { 64 return fmt.Sprintf("OpenID already in use [oid: %s]", err.OpenID) 65 } 66 67 func (err ErrOpenIDAlreadyUsed) Unwrap() error { 68 return util.ErrAlreadyExist 69 } 70 71 // AddUserOpenID adds an pre-verified/normalized OpenID URI to given user. 72 // NOTE: make sure openid.URI is normalized already 73 func AddUserOpenID(ctx context.Context, openid *UserOpenID) error { 74 used, err := isOpenIDUsed(ctx, openid.URI) 75 if err != nil { 76 return err 77 } else if used { 78 return ErrOpenIDAlreadyUsed{openid.URI} 79 } 80 81 return db.Insert(ctx, openid) 82 } 83 84 // DeleteUserOpenID deletes an openid address of given user. 85 func DeleteUserOpenID(ctx context.Context, openid *UserOpenID) (err error) { 86 var deleted int64 87 // ask to check UID 88 address := UserOpenID{ 89 UID: openid.UID, 90 } 91 if openid.ID > 0 { 92 deleted, err = db.GetEngine(ctx).ID(openid.ID).Delete(&address) 93 } else { 94 deleted, err = db.GetEngine(ctx). 95 Where("openid=?", openid.URI). 96 Delete(&address) 97 } 98 99 if err != nil { 100 return err 101 } else if deleted != 1 { 102 return ErrOpenIDNotExist 103 } 104 return nil 105 } 106 107 // ToggleUserOpenIDVisibility toggles visibility of an openid address of given user. 108 func ToggleUserOpenIDVisibility(ctx context.Context, id int64) (err error) { 109 _, err = db.GetEngine(ctx).Exec("update `user_open_id` set `show` = not `show` where `id` = ?", id) 110 return err 111 }