func (s *Service) clientCredentialsGrant(w http.ResponseWriter, r *http.Request, client *Client) {
	// Get the scope string
	scope, err := s.GetScope(r.Form.Get("scope"))
	if err != nil {
		response.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Create a new access token
	accessToken, err := s.GrantAccessToken(
		client,
		new(User),                       // empty user
		s.cnf.Oauth.AccessTokenLifetime, // expires in
		scope,
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Write the JSON access token to the response
	accessTokenRespone := &AccessTokenResponse{
		AccessToken: accessToken.Token,
		ExpiresIn:   s.cnf.Oauth.AccessTokenLifetime,
		TokenType:   TokenType,
		Scope:       accessToken.Scope,
	}
	response.WriteJSON(w, accessTokenRespone, 200)
}
func (s *Service) refreshTokenGrant(w http.ResponseWriter, r *http.Request, client *Client) {
	// Fetch the refresh token
	theRefreshToken, err := s.GetValidRefreshToken(
		r.Form.Get("refresh_token"), // refresh token
		client, // client
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Get the scope string
	scope, err := s.GetScope(r.Form.Get("scope"))
	if err != nil {
		response.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Requested scope CANNOT include any scope not originally granted
	if !util.SpaceDelimitedStringNotGreater(scope, theRefreshToken.Scope) {
		response.Error(w, errRequestedScopeCannotBeGreater.Error(), http.StatusBadRequest)
		return
	}

	// Create a new access token
	accessToken, err := s.GrantAccessToken(
		theRefreshToken.Client, // client
		theRefreshToken.User,   // user
		scope,                  // scope
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Create or retrieve a refresh token
	refreshToken, err := s.GetOrCreateRefreshToken(
		theRefreshToken.Client, // client
		theRefreshToken.User,   // user
		scope,                  // scope
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Write the JSON access token to the response
	accessTokenRespone := &AccessTokenResponse{
		ID:           accessToken.ID,
		AccessToken:  accessToken.Token,
		ExpiresIn:    s.cnf.Oauth.AccessTokenLifetime,
		TokenType:    "Bearer",
		Scope:        accessToken.Scope,
		RefreshToken: refreshToken.Token,
	}
	response.WriteJSON(w, accessTokenRespone, 200)
}
func (s *Service) authorizationCodeGrant(w http.ResponseWriter, r *http.Request, client *Client) {
	// Fetch the authorization code
	authorizationCode, err := s.getValidAuthorizationCode(
		r.Form.Get("code"), // authorization code
		client,             // client
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Redirect URI must match if it was used to obtain the authorization code
	if util.StringOrNull(r.Form.Get("redirect_uri")) != authorizationCode.RedirectURI {
		response.Error(w, errInvalidRedirectURI.Error(), http.StatusBadRequest)
		return
	}

	// Create a new access token
	accessToken, err := s.GrantAccessToken(
		authorizationCode.Client, // client
		authorizationCode.User,   // user
		authorizationCode.Scope,  // scope
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Create or retrieve a refresh token
	refreshToken, err := s.GetOrCreateRefreshToken(
		authorizationCode.Client, // client
		authorizationCode.User,   // user
		authorizationCode.Scope,  // scope
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Delete the authorization code
	s.db.Unscoped().Delete(&authorizationCode)

	// Write the JSON access token to the response
	accessTokenRespone := &AccessTokenResponse{
		ID:           accessToken.ID,
		AccessToken:  accessToken.Token,
		ExpiresIn:    s.cnf.Oauth.AccessTokenLifetime,
		TokenType:    "Bearer",
		Scope:        accessToken.Scope,
		RefreshToken: refreshToken.Token,
	}
	response.WriteJSON(w, accessTokenRespone, 200)
}
func (s *Service) refreshTokenGrant(w http.ResponseWriter, r *http.Request, client *Client) {
	// Fetch the refresh token
	theRefreshToken, err := s.GetValidRefreshToken(
		r.Form.Get("refresh_token"), // refresh token
		client, // client
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Default to the scope originally granted by the resource owner
	scope := theRefreshToken.Scope

	// If the scope is specified in the request, get the scope string
	if r.Form.Get("scope") != "" {
		scope, err = s.GetScope(r.Form.Get("scope"))
		if err != nil {
			response.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}

	// Requested scope CANNOT include any scope not originally granted
	if !util.SpaceDelimitedStringNotGreater(scope, theRefreshToken.Scope) {
		response.Error(w, ErrRequestedScopeCannotBeGreater.Error(), http.StatusBadRequest)
		return
	}

	// Log in the user
	accessToken, refreshToken, err := s.Login(
		theRefreshToken.Client,
		theRefreshToken.User,
		scope,
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Write the JSON access token to the response
	accessTokenRespone := &AccessTokenResponse{
		AccessToken:  accessToken.Token,
		ExpiresIn:    s.cnf.Oauth.AccessTokenLifetime,
		TokenType:    TokenType,
		Scope:        accessToken.Scope,
		RefreshToken: refreshToken.Token,
	}
	if accessToken.User != nil {
		accessTokenRespone.UserID = accessToken.User.ID
	}
	response.WriteJSON(w, accessTokenRespone, 200)
}
func (s *Service) passwordGrant(w http.ResponseWriter, r *http.Request, client *Client) {
	// Get user credentials from form data
	username := r.Form.Get("username") // usually an email
	password := r.Form.Get("password")

	// Authenticate the user
	user, err := s.AuthUser(username, password)
	if err != nil {
		// For security reasons, return a general error message
		response.UnauthorizedError(w, "User authentication required")
		return
	}

	// Get the scope string
	scope, err := s.GetScope(r.Form.Get("scope"))
	if err != nil {
		response.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Create a new access token
	accessToken, err := s.GrantAccessToken(
		client, // client
		user,   // user
		scope,  // scope
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Create or retrieve a refresh token
	refreshToken, err := s.GetOrCreateRefreshToken(
		client, // client
		user,   // user
		scope,  // scope
	)
	if err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// Write the JSON access token to the response
	accessTokenRespone := &AccessTokenResponse{
		ID:           accessToken.ID,
		AccessToken:  accessToken.Token,
		ExpiresIn:    s.cnf.Oauth.AccessTokenLifetime,
		TokenType:    "Bearer",
		Scope:        accessToken.Scope,
		RefreshToken: refreshToken.Token,
	}
	response.WriteJSON(w, accessTokenRespone, 200)
}
Example #6
0
// Handles health check requests (GET /v1/health)
func (s *Service) healthcheck(w http.ResponseWriter, r *http.Request) {
	rows, err := s.db.Raw("SELECT 1=1").Rows()
	defer rows.Close()

	var healthy bool
	if err == nil {
		healthy = true
	}

	response.WriteJSON(w, map[string]interface{}{
		"healthy": healthy,
	}, 200)
}
func (s *Service) introspectToken(w http.ResponseWriter, r *http.Request, client *Client) {
	// Parse the form so r.Form becomes available
	if err := r.ParseForm(); err != nil {
		response.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	token := r.Form.Get("token")
	if token == "" {
		response.Error(w, ErrTokenMissing.Error(), http.StatusBadRequest)
		return
	}

	tokenTypeHint := r.Form.Get("token_type_hint")

	if tokenTypeHint == "" {
		tokenTypeHint = accessTokenHint
	}

	var ir *IntrospectResponse

	switch tokenTypeHint {
	case accessTokenHint:
		var ok bool
		ir, ok = s.introspectAccessToken(w, token)
		if !ok {
			ir, _ = s.introspectRefreshToken(w, token, client)
		}
	case refreshTokenHint:
		var ok bool
		ir, ok = s.introspectRefreshToken(w, token, client)
		if !ok {
			ir, _ = s.introspectAccessToken(w, token)
		}
	default:
		response.Error(w, ErrTokenHintInvalid.Error(), http.StatusBadRequest)
		return
	}

	if ir == nil {
		ir = &IntrospectResponse{}
	}

	response.WriteJSON(w, ir, 200)
}