github.com/RichardKnop/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 }