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  }