github.com/jxgolibs/go-oauth2-server@v1.0.1/oauth/client.go (about)

     1  package oauth
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/RichardKnop/go-oauth2-server/models"
     9  	"github.com/RichardKnop/go-oauth2-server/util"
    10  	"github.com/RichardKnop/go-oauth2-server/util/password"
    11  	"github.com/RichardKnop/uuid"
    12  	"github.com/jinzhu/gorm"
    13  )
    14  
    15  var (
    16  	// ErrClientNotFound ...
    17  	ErrClientNotFound = errors.New("Client not found")
    18  	// ErrInvalidClientSecret ...
    19  	ErrInvalidClientSecret = errors.New("Invalid client secret")
    20  	// ErrClientIDTaken ...
    21  	ErrClientIDTaken = errors.New("Client ID taken")
    22  )
    23  
    24  // ClientExists returns true if client exists
    25  func (s *Service) ClientExists(clientID string) bool {
    26  	_, err := s.FindClientByClientID(clientID)
    27  	return err == nil
    28  }
    29  
    30  // FindClientByClientID looks up a client by client ID
    31  func (s *Service) FindClientByClientID(clientID string) (*models.OauthClient, error) {
    32  	// Client IDs are case insensitive
    33  	client := new(models.OauthClient)
    34  	notFound := s.db.Where("key = LOWER(?)", clientID).
    35  		First(client).RecordNotFound()
    36  
    37  	// Not found
    38  	if notFound {
    39  		return nil, ErrClientNotFound
    40  	}
    41  
    42  	return client, nil
    43  }
    44  
    45  // CreateClient saves a new client to database
    46  func (s *Service) CreateClient(clientID, secret, redirectURI string) (*models.OauthClient, error) {
    47  	return s.createClientCommon(s.db, clientID, secret, redirectURI)
    48  }
    49  
    50  // CreateClientTx saves a new client to database using injected db object
    51  func (s *Service) CreateClientTx(tx *gorm.DB, clientID, secret, redirectURI string) (*models.OauthClient, error) {
    52  	return s.createClientCommon(tx, clientID, secret, redirectURI)
    53  }
    54  
    55  // AuthClient authenticates client
    56  func (s *Service) AuthClient(clientID, secret string) (*models.OauthClient, error) {
    57  	// Fetch the client
    58  	client, err := s.FindClientByClientID(clientID)
    59  	if err != nil {
    60  		return nil, ErrClientNotFound
    61  	}
    62  
    63  	// Verify the secret
    64  	if password.VerifyPassword(client.Secret, secret) != nil {
    65  		return nil, ErrInvalidClientSecret
    66  	}
    67  
    68  	return client, nil
    69  }
    70  
    71  func (s *Service) createClientCommon(db *gorm.DB, clientID, secret, redirectURI string) (*models.OauthClient, error) {
    72  	// Check client ID
    73  	if s.ClientExists(clientID) {
    74  		return nil, ErrClientIDTaken
    75  	}
    76  
    77  	// Hash password
    78  	secretHash, err := password.HashPassword(secret)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	client := &models.OauthClient{
    84  		MyGormModel: models.MyGormModel{
    85  			ID:        uuid.New(),
    86  			CreatedAt: time.Now().UTC(),
    87  		},
    88  		Key:         strings.ToLower(clientID),
    89  		Secret:      string(secretHash),
    90  		RedirectURI: util.StringOrNull(redirectURI),
    91  	}
    92  	if err := db.Create(client).Error; err != nil {
    93  		return nil, err
    94  	}
    95  	return client, nil
    96  }