Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Vouch Proxy supports many OAuth login providers and can enforce authentication t
* [AWS Cognito](https://github.com/vouch/vouch-proxy/issues/105)
* Keycloak
* [OAuth2 Server Library for PHP](https://github.com/vouch/vouch-proxy/issues/99)
* [HomeAssistant](https://developers.home-assistant.io/docs/en/auth_api.html)
* most other OpenID Connect (OIDC) providers

Please do let us know when you have deployed Vouch Proxy with your preffered IdP or library so we can update the list.
Expand Down
33 changes: 33 additions & 0 deletions config/config.yml_example_homeassistant
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# vouch config
# bare minimum to get vouch running with HomeAssistant

vouch:
# logLevel: debug
logLevel: info

# domains:
# valid domains that the jwt cookies can be set into
# the callback_urls will be to these domains
domains:
- yourdomain.com

# set allowAllUsers: true to use Vouch Proxy to just accept anyone who can authenticate at the configured provider
allowAllUsers: false

# whiteList - (optional) allows only the listed usernames
# usernames are usually email addresses (google, most oidc providers) or login/username for github and github enterprise
# using static value for HomeAssistant
whiteList:
- homeassistant

# Setting publicAccess: true will accept all requests, even without a cookie.
publicAccess: false

oauth:
# HomeAssistant Auth
# https://developers.home-assistant.io/docs/en/auth_api.html
provider: homeassistant
client_id: https://vouch.yourdomain.com
callback_url: https://vouch.yourdomain.com/auth
auth_url: https://homeassistant.yourdomain.com/auth/authorize
token_url: https://homeassistant.yourdomain.com/auth/token
11 changes: 11 additions & 0 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,10 @@ func getUserInfo(r *http.Request, user *structs.User, customClaims *structs.Cust
if err != nil {
return err
}
if cfg.GenOAuth.Provider == cfg.Providers.HomeAssistant {
ptokens.PAccessToken = providerToken.Extra("access_token").(string)
return getUserInfoFromHomeAssistant(r, user, customClaims)
}
ptokens.PAccessToken = providerToken.AccessToken
ptokens.PIdToken = providerToken.Extra("id_token").(string)
log.Debugf("ptokens: %+v", ptokens)
Expand Down Expand Up @@ -705,6 +709,13 @@ func getUserInfoFromIndieAuth(r *http.Request, user *structs.User, customClaims
return nil
}

// More info: https://developers.home-assistant.io/docs/en/auth_api.html
func getUserInfoFromHomeAssistant(r *http.Request, user *structs.User, customClaims *structs.CustomClaims) (rerr error) {
// Home assistant does not provide an API to query username, so we statically set it to "homeassistant"
user.Username = "homeassistant"
return nil
}

type adfsTokenRes struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
Expand Down
26 changes: 14 additions & 12 deletions pkg/cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ type oauthConfig struct {

// OAuthProviders holds the stings for
type OAuthProviders struct {
Google string
GitHub string
IndieAuth string
ADFS string
OIDC string
Google string
GitHub string
IndieAuth string
HomeAssistant string
ADFS string
OIDC string
}

type branding struct {
Expand Down Expand Up @@ -121,11 +122,12 @@ var (

// Providers static strings to test against
Providers = &OAuthProviders{
Google: "google",
GitHub: "github",
IndieAuth: "indieauth",
ADFS: "adfs",
OIDC: "oidc",
Google: "google",
GitHub: "github",
IndieAuth: "indieauth",
HomeAssistant: "homeassistant",
ADFS: "adfs",
OIDC: "oidc",
}

// RequiredOptions must have these fields set for minimum viable config
Expand Down Expand Up @@ -330,14 +332,14 @@ func BasicTest() error {
case GenOAuth.ClientID == "":
// everyone has a clientID
return errors.New("configuration error: oauth.client_id not found")
case GenOAuth.Provider != Providers.IndieAuth && GenOAuth.Provider != Providers.ADFS && GenOAuth.Provider != Providers.OIDC && GenOAuth.ClientSecret == "":
case GenOAuth.Provider != Providers.IndieAuth && GenOAuth.Provider != Providers.HomeAssistant && GenOAuth.Provider != Providers.ADFS && GenOAuth.Provider != Providers.OIDC && GenOAuth.ClientSecret == "":
// everyone except IndieAuth has a clientSecret
// ADFS and OIDC providers also do not require this, but can have it optionally set.
return errors.New("configuration error: o`auth.client_secret not found")
case GenOAuth.Provider != Providers.Google && GenOAuth.AuthURL == "":
// everyone except IndieAuth and Google has an authURL
return errors.New("configuration error: oauth.auth_url not found")
case GenOAuth.Provider != Providers.Google && GenOAuth.Provider != Providers.IndieAuth && GenOAuth.Provider != Providers.ADFS && GenOAuth.UserInfoURL == "":
case GenOAuth.Provider != Providers.Google && GenOAuth.Provider != Providers.IndieAuth && GenOAuth.Provider != Providers.HomeAssistant && GenOAuth.Provider != Providers.ADFS && GenOAuth.UserInfoURL == "":
// everyone except IndieAuth, Google and ADFS has an userInfoURL
return errors.New("configuration error: oauth.user_info_url not found")
}
Expand Down