mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-30 09:27:19 +02:00
authorize: move impersonation into session/service account (#1765)
* move impersonation into session/service account * replace frontend statik * fix data race * move JWT filling to separate function, break up functions * maybe fix data race * fix code climate issue
This commit is contained in:
parent
1466f4e5a0
commit
a6bc9f492f
16 changed files with 328 additions and 162 deletions
|
@ -10,7 +10,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
@ -25,8 +24,6 @@ import (
|
|||
"github.com/pomerium/pomerium/internal/log"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -180,46 +177,7 @@ func (e *Evaluator) JWTPayload(req *Request) map[string]interface{} {
|
|||
payload := map[string]interface{}{
|
||||
"iss": e.authenticateHost,
|
||||
}
|
||||
if u, err := url.Parse(req.HTTP.URL); err == nil {
|
||||
payload["aud"] = u.Hostname()
|
||||
}
|
||||
if s, ok := req.DataBrokerData.Get("type.googleapis.com/session.Session", req.Session.ID).(*session.Session); ok {
|
||||
payload["jti"] = s.GetId()
|
||||
if tm, err := ptypes.Timestamp(s.GetIdToken().GetExpiresAt()); err == nil {
|
||||
payload["exp"] = tm.Unix()
|
||||
}
|
||||
if tm, err := ptypes.Timestamp(s.GetIdToken().GetIssuedAt()); err == nil {
|
||||
payload["iat"] = tm.Unix()
|
||||
}
|
||||
if u, ok := req.DataBrokerData.Get("type.googleapis.com/user.User", s.GetUserId()).(*user.User); ok {
|
||||
payload["sub"] = u.GetId()
|
||||
payload["user"] = u.GetId()
|
||||
payload["email"] = u.GetEmail()
|
||||
}
|
||||
if du, ok := req.DataBrokerData.Get("type.googleapis.com/directory.User", s.GetUserId()).(*directory.User); ok {
|
||||
if du.GetEmail() != "" {
|
||||
payload["email"] = du.GetEmail()
|
||||
}
|
||||
var groupNames []string
|
||||
for _, groupID := range du.GetGroupIds() {
|
||||
if dg, ok := req.DataBrokerData.Get("type.googleapis.com/directory.Group", groupID).(*directory.Group); ok {
|
||||
groupNames = append(groupNames, dg.Name)
|
||||
}
|
||||
}
|
||||
var groups []string
|
||||
groups = append(groups, du.GetGroupIds()...)
|
||||
groups = append(groups, groupNames...)
|
||||
payload["groups"] = groups
|
||||
}
|
||||
}
|
||||
|
||||
if req.Session.ImpersonateEmail != "" {
|
||||
payload["email"] = req.Session.ImpersonateEmail
|
||||
}
|
||||
if len(req.Session.ImpersonateGroups) > 0 {
|
||||
payload["groups"] = req.Session.ImpersonateGroups
|
||||
}
|
||||
|
||||
req.fillJWTPayload(payload)
|
||||
return payload
|
||||
}
|
||||
|
||||
|
@ -305,10 +263,18 @@ func (e *Evaluator) newInput(req *Request, isValidClientCertificate bool) *input
|
|||
if i.DataBrokerData.Session == nil {
|
||||
i.DataBrokerData.Session = req.DataBrokerData.Get(serviceAccountTypeURL, req.Session.ID)
|
||||
}
|
||||
if obj, ok := i.DataBrokerData.Session.(interface{ GetUserId() string }); ok {
|
||||
i.DataBrokerData.User = req.DataBrokerData.Get(userTypeURL, obj.GetUserId())
|
||||
var userIDs []string
|
||||
if obj, ok := i.DataBrokerData.Session.(interface{ GetUserId() string }); ok && obj.GetUserId() != "" {
|
||||
userIDs = append(userIDs, obj.GetUserId())
|
||||
}
|
||||
if obj, ok := i.DataBrokerData.Session.(interface{ GetImpersonateUserId() string }); ok && obj.GetImpersonateUserId() != "" {
|
||||
userIDs = append(userIDs, obj.GetImpersonateUserId())
|
||||
}
|
||||
|
||||
user, ok := req.DataBrokerData.Get(directoryUserTypeURL, obj.GetUserId()).(*directory.User)
|
||||
for _, userID := range userIDs {
|
||||
i.DataBrokerData.User = req.DataBrokerData.Get(userTypeURL, userID)
|
||||
|
||||
user, ok := req.DataBrokerData.Get(directoryUserTypeURL, userID).(*directory.User)
|
||||
if ok {
|
||||
var groups []string
|
||||
for _, groupID := range user.GetGroupIds() {
|
||||
|
@ -331,31 +297,6 @@ func (e *Evaluator) newInput(req *Request, isValidClientCertificate bool) *input
|
|||
return i
|
||||
}
|
||||
|
||||
type (
|
||||
// Request is the request data used for the evaluator.
|
||||
Request struct {
|
||||
DataBrokerData DataBrokerData `json:"databroker_data"`
|
||||
HTTP RequestHTTP `json:"http"`
|
||||
Session RequestSession `json:"session"`
|
||||
CustomPolicies []string
|
||||
}
|
||||
|
||||
// RequestHTTP is the HTTP field in the request.
|
||||
RequestHTTP struct {
|
||||
Method string `json:"method"`
|
||||
URL string `json:"url"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
ClientCertificate string `json:"client_certificate"`
|
||||
}
|
||||
|
||||
// RequestSession is the session field in the request.
|
||||
RequestSession struct {
|
||||
ID string `json:"id"`
|
||||
ImpersonateEmail string `json:"impersonate_email"`
|
||||
ImpersonateGroups []string `json:"impersonate_groups"`
|
||||
}
|
||||
)
|
||||
|
||||
// Result is the result of evaluation.
|
||||
type Result struct {
|
||||
Status int
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"gopkg.in/square/go-jose.v2/jwt"
|
||||
|
||||
"github.com/pomerium/pomerium/config"
|
||||
|
@ -58,9 +59,7 @@ func TestJSONMarshal(t *testing.T) {
|
|||
ClientCertificate: "CLIENT_CERTIFICATE",
|
||||
},
|
||||
Session: RequestSession{
|
||||
ID: "SESSION_ID",
|
||||
ImpersonateEmail: "y@example.com",
|
||||
ImpersonateGroups: []string{"group1"},
|
||||
ID: "SESSION_ID",
|
||||
},
|
||||
}, true))
|
||||
assert.JSONEq(t, `{
|
||||
|
@ -79,9 +78,7 @@ func TestJSONMarshal(t *testing.T) {
|
|||
"url": "https://example.com"
|
||||
},
|
||||
"session": {
|
||||
"id": "SESSION_ID",
|
||||
"impersonate_email": "y@example.com",
|
||||
"impersonate_groups": ["group1"]
|
||||
"id": "SESSION_ID"
|
||||
},
|
||||
"is_valid_client_certificate": true
|
||||
}`, string(bs))
|
||||
|
@ -158,6 +155,7 @@ func TestEvaluator_JWTPayload(t *testing.T) {
|
|||
ExpiresAt: nowPb,
|
||||
IssuedAt: nowPb,
|
||||
},
|
||||
ExpiresAt: nowPb,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -174,6 +172,31 @@ func TestEvaluator_JWTPayload(t *testing.T) {
|
|||
"iat": now.Unix(),
|
||||
},
|
||||
},
|
||||
{
|
||||
"with service account",
|
||||
&Request{
|
||||
DataBrokerData: DataBrokerData{
|
||||
"type.googleapis.com/user.ServiceAccount": map[string]interface{}{
|
||||
"SERVICE_ACCOUNT_ID": &user.ServiceAccount{
|
||||
Id: "SERVICE_ACCOUNT_ID",
|
||||
IssuedAt: nowPb,
|
||||
ExpiresAt: nowPb,
|
||||
},
|
||||
},
|
||||
},
|
||||
HTTP: RequestHTTP{URL: "https://example.com"},
|
||||
Session: RequestSession{
|
||||
ID: "SERVICE_ACCOUNT_ID",
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"iss": "authn.example.com",
|
||||
"jti": "SERVICE_ACCOUNT_ID",
|
||||
"aud": "example.com",
|
||||
"exp": now.Unix(),
|
||||
"iat": now.Unix(),
|
||||
},
|
||||
},
|
||||
{
|
||||
"with user",
|
||||
&Request{
|
||||
|
@ -252,12 +275,22 @@ func TestEvaluator_JWTPayload(t *testing.T) {
|
|||
&Request{
|
||||
HTTP: RequestHTTP{URL: "https://example.com"},
|
||||
Session: RequestSession{
|
||||
ImpersonateEmail: "user@example.com",
|
||||
ImpersonateGroups: []string{"admin", "test"},
|
||||
ID: "SESSION_ID",
|
||||
},
|
||||
DataBrokerData: DataBrokerData{
|
||||
"type.googleapis.com/session.Session": map[string]interface{}{
|
||||
"SESSION_ID": &session.Session{
|
||||
Id: "SESSION_ID",
|
||||
UserId: "USER_ID",
|
||||
ImpersonateEmail: proto.String("user@example.com"),
|
||||
ImpersonateGroups: []string{"admin", "test"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"iss": "authn.example.com",
|
||||
"jti": "SESSION_ID",
|
||||
"aud": "example.com",
|
||||
"email": "user@example.com",
|
||||
"groups": []string{"admin", "test"},
|
||||
|
|
|
@ -14,7 +14,7 @@ all_allowed_groups := get_allowed_groups(route_policy)
|
|||
all_allowed_users := get_allowed_users(route_policy)
|
||||
all_allowed_idp_claims := get_allowed_idp_claims(route_policy)
|
||||
|
||||
is_impersonating := count(input.session.impersonate_email) > 0
|
||||
is_impersonating := count(session.impersonate_email) > 0
|
||||
|
||||
# allow public
|
||||
allow {
|
||||
|
@ -52,14 +52,14 @@ allow {
|
|||
# allow by impersonate email
|
||||
allow {
|
||||
is_impersonating
|
||||
all_allowed_users[_] = input.session.impersonate_email
|
||||
all_allowed_users[_] = session.impersonate_email
|
||||
}
|
||||
|
||||
# allow by impersonate group
|
||||
allow {
|
||||
is_impersonating
|
||||
some group
|
||||
input.session.impersonate_groups[_] = group
|
||||
session.impersonate_groups[_] = group
|
||||
all_allowed_groups[_] = group
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ allow {
|
|||
allow {
|
||||
is_impersonating
|
||||
some domain
|
||||
email_in_domain(input.session.impersonate_email, all_allowed_domains[domain])
|
||||
email_in_domain(session.impersonate_email, all_allowed_domains[domain])
|
||||
}
|
||||
|
||||
# allow by arbitrary idp claims
|
||||
|
|
|
@ -15,7 +15,7 @@ test_email_allowed {
|
|||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_impersonate_email_not_allowed {
|
||||
|
@ -26,14 +26,14 @@ test_impersonate_email_not_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": "y@example.com"
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "y@example.com" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_impersonate_email_allowed {
|
||||
|
@ -44,14 +44,14 @@ test_impersonate_email_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": "y@example.com"
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "y@example.com" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_group_allowed {
|
||||
|
@ -81,7 +81,7 @@ test_impersonate_groups_not_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": "y@example.com", "impersonate_groups": ["2"]
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
|
@ -89,7 +89,7 @@ test_impersonate_groups_not_allowed {
|
|||
"groups": ["1"]
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "y@example.com", "impersonate_groups": ["2"] }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_impersonate_groups_allowed {
|
||||
|
@ -100,7 +100,7 @@ test_impersonate_groups_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": "y@example.com", "impersonate_groups": ["2"]
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
|
@ -110,7 +110,7 @@ test_impersonate_groups_allowed {
|
|||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "y@example.com", "impersonate_groups": ["2"] }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_domain_allowed {
|
||||
|
@ -121,14 +121,14 @@ test_domain_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": ""
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_impersonate_domain_not_allowed {
|
||||
|
@ -139,14 +139,14 @@ test_impersonate_domain_not_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": "y@example1.com"
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "y@example1.com" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_impersonate_domain_allowed {
|
||||
|
@ -157,14 +157,14 @@ test_impersonate_domain_allowed {
|
|||
}] with
|
||||
input.databroker_data as {
|
||||
"session": {
|
||||
"user_id": "user1"
|
||||
"user_id": "user1", "impersonate_email": "y@example1.com"
|
||||
},
|
||||
"user": {
|
||||
"email": "x@example.com"
|
||||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "y@example1.com" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_idp_claims_allowed {
|
||||
|
@ -183,7 +183,7 @@ test_idp_claims_allowed {
|
|||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
||||
test_example {
|
||||
|
@ -395,7 +395,7 @@ test_any_authenticated_user_allowed {
|
|||
}
|
||||
} with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
test_any_authenticated_user_denied {
|
||||
not allow with
|
||||
|
@ -404,5 +404,5 @@ test_any_authenticated_user_denied {
|
|||
"AllowAnyAuthenticatedUser": true
|
||||
}] with
|
||||
input.http as { "url": "http://example.com" } with
|
||||
input.session as { "id": "session1", "impersonate_email": "" }
|
||||
input.session as { "id": "session1" }
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
100
authorize/evaluator/request.go
Normal file
100
authorize/evaluator/request.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package evaluator
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/directory"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
)
|
||||
|
||||
type (
|
||||
// Request is the request data used for the evaluator.
|
||||
Request struct {
|
||||
DataBrokerData DataBrokerData `json:"databroker_data"`
|
||||
HTTP RequestHTTP `json:"http"`
|
||||
Session RequestSession `json:"session"`
|
||||
CustomPolicies []string
|
||||
}
|
||||
|
||||
// RequestHTTP is the HTTP field in the request.
|
||||
RequestHTTP struct {
|
||||
Method string `json:"method"`
|
||||
URL string `json:"url"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
ClientCertificate string `json:"client_certificate"`
|
||||
}
|
||||
|
||||
// RequestSession is the session field in the request.
|
||||
RequestSession struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
)
|
||||
|
||||
type sessionOrServiceAccount interface {
|
||||
GetId() string
|
||||
GetExpiresAt() *timestamppb.Timestamp
|
||||
GetIssuedAt() *timestamppb.Timestamp
|
||||
GetUserId() string
|
||||
GetImpersonateEmail() string
|
||||
GetImpersonateGroups() []string
|
||||
GetImpersonateUserId() string
|
||||
}
|
||||
|
||||
func (req *Request) fillJWTPayload(payload map[string]interface{}) {
|
||||
if u, err := url.Parse(req.HTTP.URL); err == nil {
|
||||
payload["aud"] = u.Hostname()
|
||||
}
|
||||
|
||||
if s, ok := req.DataBrokerData.Get("type.googleapis.com/session.Session", req.Session.ID).(*session.Session); ok {
|
||||
req.fillJWTPayloadSessionOrServiceAccount(payload, s)
|
||||
}
|
||||
|
||||
if sa, ok := req.DataBrokerData.Get("type.googleapis.com/user.ServiceAccount", req.Session.ID).(*user.ServiceAccount); ok {
|
||||
req.fillJWTPayloadSessionOrServiceAccount(payload, sa)
|
||||
}
|
||||
}
|
||||
|
||||
func (req *Request) fillJWTPayloadSessionOrServiceAccount(payload map[string]interface{}, s sessionOrServiceAccount) {
|
||||
payload["jti"] = s.GetId()
|
||||
if s.GetExpiresAt().IsValid() {
|
||||
payload["exp"] = s.GetExpiresAt().AsTime().Unix()
|
||||
}
|
||||
if s.GetIssuedAt().IsValid() {
|
||||
payload["iat"] = s.GetIssuedAt().AsTime().Unix()
|
||||
}
|
||||
|
||||
userID := s.GetUserId()
|
||||
if s.GetImpersonateUserId() != "" {
|
||||
userID = s.GetImpersonateUserId()
|
||||
}
|
||||
if u, ok := req.DataBrokerData.Get("type.googleapis.com/user.User", userID).(*user.User); ok {
|
||||
payload["sub"] = u.GetId()
|
||||
payload["user"] = u.GetId()
|
||||
payload["email"] = u.GetEmail()
|
||||
}
|
||||
if du, ok := req.DataBrokerData.Get("type.googleapis.com/directory.User", userID).(*directory.User); ok {
|
||||
if du.GetEmail() != "" {
|
||||
payload["email"] = du.GetEmail()
|
||||
}
|
||||
var groupNames []string
|
||||
for _, groupID := range du.GetGroupIds() {
|
||||
if dg, ok := req.DataBrokerData.Get("type.googleapis.com/directory.Group", groupID).(*directory.Group); ok {
|
||||
groupNames = append(groupNames, dg.Name)
|
||||
}
|
||||
}
|
||||
var groups []string
|
||||
groups = append(groups, du.GetGroupIds()...)
|
||||
groups = append(groups, groupNames...)
|
||||
payload["groups"] = groups
|
||||
}
|
||||
|
||||
if s.GetImpersonateEmail() != "" {
|
||||
payload["email"] = s.GetImpersonateEmail()
|
||||
}
|
||||
if len(s.GetImpersonateGroups()) > 0 {
|
||||
payload["groups"] = s.GetImpersonateGroups()
|
||||
}
|
||||
}
|
|
@ -230,9 +230,7 @@ func (a *Authorize) getEvaluatorRequestFromCheckRequest(in *envoy_service_auth_v
|
|||
}
|
||||
if sessionState != nil {
|
||||
req.Session = evaluator.RequestSession{
|
||||
ID: sessionState.ID,
|
||||
ImpersonateEmail: sessionState.ImpersonateEmail,
|
||||
ImpersonateGroups: sessionState.ImpersonateGroups,
|
||||
ID: sessionState.ID,
|
||||
}
|
||||
}
|
||||
p := a.getMatchingPolicy(requestURL)
|
||||
|
|
|
@ -92,9 +92,7 @@ func Test_getEvaluatorRequest(t *testing.T) {
|
|||
)
|
||||
expect := &evaluator.Request{
|
||||
Session: evaluator.RequestSession{
|
||||
ID: "SESSION_ID",
|
||||
ImpersonateEmail: "foo@example.com",
|
||||
ImpersonateGroups: []string{"admin", "test"},
|
||||
ID: "SESSION_ID",
|
||||
},
|
||||
HTTP: evaluator.RequestHTTP{
|
||||
Method: "GET",
|
||||
|
|
|
@ -22,14 +22,12 @@ import (
|
|||
var (
|
||||
errObtainCertFailed = errors.New("obtain cert failed")
|
||||
errRenewCertFailed = errors.New("renew cert failed")
|
||||
|
||||
checkInterval = time.Minute * 10
|
||||
acmeTemplate = certmagic.DefaultACME
|
||||
)
|
||||
|
||||
// Manager manages TLS certificates.
|
||||
type Manager struct {
|
||||
src config.Source
|
||||
src config.Source
|
||||
acmeTemplate certmagic.ACMEManager
|
||||
|
||||
mu sync.RWMutex
|
||||
config *config.Config
|
||||
|
@ -42,6 +40,14 @@ type Manager struct {
|
|||
|
||||
// New creates a new autocert manager.
|
||||
func New(src config.Source) (*Manager, error) {
|
||||
return newManager(context.Background(), src, certmagic.DefaultACME, time.Minute*10)
|
||||
}
|
||||
|
||||
func newManager(ctx context.Context,
|
||||
src config.Source,
|
||||
acmeTemplate certmagic.ACMEManager,
|
||||
checkInterval time.Duration,
|
||||
) (*Manager, error) {
|
||||
// set certmagic default storage cache, otherwise cert renewal loop will be based off
|
||||
// certmagic's own default location
|
||||
certmagic.Default.Storage = &certmagic.FileStorage{
|
||||
|
@ -50,8 +56,9 @@ func New(src config.Source) (*Manager, error) {
|
|||
certmagic.Default.Logger = log.ZapLogger().With(zap.String("service", "autocert"))
|
||||
|
||||
mgr := &Manager{
|
||||
src: src,
|
||||
certmagic: certmagic.NewDefault(),
|
||||
src: src,
|
||||
acmeTemplate: acmeTemplate,
|
||||
certmagic: certmagic.NewDefault(),
|
||||
}
|
||||
err := mgr.update(src.GetConfig())
|
||||
if err != nil {
|
||||
|
@ -71,11 +78,16 @@ func New(src config.Source) (*Manager, error) {
|
|||
ticker := time.NewTicker(checkInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
err := mgr.renewConfigCerts()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("autocert: error updating config")
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
err := mgr.renewConfigCerts()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("autocert: error updating config")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -92,7 +104,7 @@ func (mgr *Manager) getCertMagicConfig(options *config.Options) (*certmagic.Conf
|
|||
return nil, fmt.Errorf("config: failed caching cert: %w", err)
|
||||
}
|
||||
}
|
||||
acmeMgr := certmagic.NewACMEManager(mgr.certmagic, acmeTemplate)
|
||||
acmeMgr := certmagic.NewACMEManager(mgr.certmagic, mgr.acmeTemplate)
|
||||
acmeMgr.Agreed = true
|
||||
if options.AutocertOptions.UseStaging {
|
||||
acmeMgr.CA = acmeMgr.TestCA
|
||||
|
|
|
@ -2,6 +2,7 @@ package autocert
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
|
@ -122,6 +123,9 @@ func newMockACME(srv *httptest.Server) http.Handler {
|
|||
}
|
||||
|
||||
func TestConfig(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
var mockACME http.Handler
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
mockACME.ServeHTTP(w, r)
|
||||
|
@ -140,23 +144,12 @@ func TestConfig(t *testing.T) {
|
|||
addr := li.Addr().String()
|
||||
_ = li.Close()
|
||||
|
||||
oAcmeTemplate := acmeTemplate
|
||||
defer func() { acmeTemplate = oAcmeTemplate }()
|
||||
acmeTemplate = certmagic.ACMEManager{
|
||||
CA: srv.URL + "/acme/directory",
|
||||
TestCA: srv.URL + "/acme/directory",
|
||||
}
|
||||
|
||||
oCheckInterval := checkInterval
|
||||
defer func() { checkInterval = oCheckInterval }()
|
||||
checkInterval = time.Second
|
||||
|
||||
p1 := config.Policy{
|
||||
From: "http://from.example.com", To: "http://to.example.com",
|
||||
}
|
||||
_ = p1.Validate()
|
||||
|
||||
mgr, err := New(config.NewStaticSource(&config.Config{
|
||||
mgr, err := newManager(ctx, config.NewStaticSource(&config.Config{
|
||||
Options: &config.Options{
|
||||
AutocertOptions: config.AutocertOptions{
|
||||
Enable: true,
|
||||
|
@ -167,7 +160,10 @@ func TestConfig(t *testing.T) {
|
|||
HTTPRedirectAddr: addr,
|
||||
Policies: []config.Policy{p1},
|
||||
},
|
||||
}))
|
||||
}), certmagic.ACMEManager{
|
||||
CA: srv.URL + "/acme/directory",
|
||||
TestCA: srv.URL + "/acme/directory",
|
||||
}, time.Second)
|
||||
if !assert.NoError(t, err) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/golang/protobuf/ptypes"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/identity"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||
|
@ -71,3 +72,8 @@ func (x *Session) SetRawIDToken(rawIDToken string) {
|
|||
}
|
||||
x.IdToken.Raw = rawIDToken
|
||||
}
|
||||
|
||||
// GetIssuedAt returns the issued at timestamp for the id token.
|
||||
func (x *Session) GetIssuedAt() *timestamppb.Timestamp {
|
||||
return x.GetIdToken().GetIssuedAt()
|
||||
}
|
||||
|
|
|
@ -182,14 +182,17 @@ type Session struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
ExpiresAt *timestamp.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
IdToken *IDToken `protobuf:"bytes,6,opt,name=id_token,json=idToken,proto3" json:"id_token,omitempty"`
|
||||
OauthToken *OAuthToken `protobuf:"bytes,7,opt,name=oauth_token,json=oauthToken,proto3" json:"oauth_token,omitempty"`
|
||||
Claims map[string]*_struct.ListValue `protobuf:"bytes,9,rep,name=claims,proto3" json:"claims,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Audience []string `protobuf:"bytes,10,rep,name=audience,proto3" json:"audience,omitempty"`
|
||||
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
ExpiresAt *timestamp.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
IdToken *IDToken `protobuf:"bytes,6,opt,name=id_token,json=idToken,proto3" json:"id_token,omitempty"`
|
||||
OauthToken *OAuthToken `protobuf:"bytes,7,opt,name=oauth_token,json=oauthToken,proto3" json:"oauth_token,omitempty"`
|
||||
Claims map[string]*_struct.ListValue `protobuf:"bytes,9,rep,name=claims,proto3" json:"claims,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Audience []string `protobuf:"bytes,10,rep,name=audience,proto3" json:"audience,omitempty"`
|
||||
ImpersonateUserId *string `protobuf:"bytes,11,opt,name=impersonate_user_id,json=impersonateUserId,proto3,oneof" json:"impersonate_user_id,omitempty"`
|
||||
ImpersonateEmail *string `protobuf:"bytes,12,opt,name=impersonate_email,json=impersonateEmail,proto3,oneof" json:"impersonate_email,omitempty"`
|
||||
ImpersonateGroups []string `protobuf:"bytes,13,rep,name=impersonate_groups,json=impersonateGroups,proto3" json:"impersonate_groups,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Session) Reset() {
|
||||
|
@ -280,6 +283,27 @@ func (x *Session) GetAudience() []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *Session) GetImpersonateUserId() string {
|
||||
if x != nil && x.ImpersonateUserId != nil {
|
||||
return *x.ImpersonateUserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Session) GetImpersonateEmail() string {
|
||||
if x != nil && x.ImpersonateEmail != nil {
|
||||
return *x.ImpersonateEmail
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Session) GetImpersonateGroups() []string {
|
||||
if x != nil {
|
||||
return x.ImpersonateGroups
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_session_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_session_proto_rawDesc = []byte{
|
||||
|
@ -311,7 +335,7 @@ var file_session_proto_rawDesc = []byte{
|
|||
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78,
|
||||
0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65,
|
||||
0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x93, 0x03, 0x0a,
|
||||
0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd7, 0x04, 0x0a,
|
||||
0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
|
||||
|
@ -331,16 +355,28 @@ var file_session_proto_rawDesc = []byte{
|
|||
0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6c, 0x61, 0x69,
|
||||
0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x08, 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x1a, 0x55, 0x0a, 0x0b, 0x43,
|
||||
0x6c, 0x61, 0x69, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
||||
0x38, 0x01, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x70, 0x6f, 0x6d, 0x65, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x70, 0x6f, 0x6d, 0x65, 0x72, 0x69,
|
||||
0x75, 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x65, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x09, 0x52, 0x08, 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x13, 0x69,
|
||||
0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x65,
|
||||
0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01,
|
||||
0x12, 0x30, 0x0a, 0x11, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x10, 0x69,
|
||||
0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x88,
|
||||
0x01, 0x01, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74,
|
||||
0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11,
|
||||
0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70,
|
||||
0x73, 0x1a, 0x55, 0x0a, 0x0b, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x16, 0x0a, 0x14, 0x5f, 0x69, 0x6d, 0x70,
|
||||
0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64,
|
||||
0x42, 0x14, 0x0a, 0x12, 0x5f, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65,
|
||||
0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6d, 0x65, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x70, 0x6f,
|
||||
0x6d, 0x65, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f,
|
||||
0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -423,6 +459,7 @@ func file_session_proto_init() {
|
|||
}
|
||||
}
|
||||
}
|
||||
file_session_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
|
|
@ -30,4 +30,8 @@ message Session {
|
|||
OAuthToken oauth_token = 7;
|
||||
map<string, google.protobuf.ListValue> claims = 9;
|
||||
repeated string audience = 10;
|
||||
|
||||
optional string impersonate_user_id = 11;
|
||||
optional string impersonate_email = 12;
|
||||
repeated string impersonate_groups = 13;
|
||||
}
|
||||
|
|
|
@ -166,10 +166,13 @@ type ServiceAccount struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
ExpiresAt *timestamp.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
IssuedAt *timestamp.Timestamp `protobuf:"bytes,4,opt,name=issued_at,json=issuedAt,proto3" json:"issued_at,omitempty"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
ExpiresAt *timestamp.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
IssuedAt *timestamp.Timestamp `protobuf:"bytes,4,opt,name=issued_at,json=issuedAt,proto3" json:"issued_at,omitempty"`
|
||||
ImpersonateUserId *string `protobuf:"bytes,5,opt,name=impersonate_user_id,json=impersonateUserId,proto3,oneof" json:"impersonate_user_id,omitempty"`
|
||||
ImpersonateEmail *string `protobuf:"bytes,6,opt,name=impersonate_email,json=impersonateEmail,proto3,oneof" json:"impersonate_email,omitempty"`
|
||||
ImpersonateGroups []string `protobuf:"bytes,7,rep,name=impersonate_groups,json=impersonateGroups,proto3" json:"impersonate_groups,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ServiceAccount) Reset() {
|
||||
|
@ -232,6 +235,27 @@ func (x *ServiceAccount) GetIssuedAt() *timestamp.Timestamp {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *ServiceAccount) GetImpersonateUserId() string {
|
||||
if x != nil && x.ImpersonateUserId != nil {
|
||||
return *x.ImpersonateUserId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ServiceAccount) GetImpersonateEmail() string {
|
||||
if x != nil && x.ImpersonateEmail != nil {
|
||||
return *x.ImpersonateEmail
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ServiceAccount) GetImpersonateGroups() []string {
|
||||
if x != nil {
|
||||
return x.ImpersonateGroups
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_user_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_user_proto_rawDesc = []byte{
|
||||
|
@ -257,7 +281,7 @@ var file_user_proto_rawDesc = []byte{
|
|||
0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xad, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf1, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73,
|
||||
|
@ -268,10 +292,23 @@ var file_user_proto_rawDesc = []byte{
|
|||
0x37, 0x0a, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08,
|
||||
0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x41, 0x74, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6d, 0x65, 0x72, 0x69, 0x75, 0x6d, 0x2f,
|
||||
0x70, 0x6f, 0x6d, 0x65, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x72, 0x70,
|
||||
0x63, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x41, 0x74, 0x12, 0x33, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x65,
|
||||
0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f,
|
||||
0x6e, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a,
|
||||
0x11, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6d, 0x61,
|
||||
0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x10, 0x69, 0x6d, 0x70, 0x65,
|
||||
0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x88, 0x01, 0x01, 0x12,
|
||||
0x2d, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x67,
|
||||
0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6d, 0x70,
|
||||
0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x42, 0x16,
|
||||
0x0a, 0x14, 0x5f, 0x69, 0x6d, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x69, 0x6d, 0x70, 0x65, 0x72,
|
||||
0x73, 0x6f, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x2c, 0x5a, 0x2a,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6d, 0x65, 0x72,
|
||||
0x69, 0x75, 0x6d, 0x2f, 0x70, 0x6f, 0x6d, 0x65, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x70, 0x6b, 0x67,
|
||||
0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -350,6 +387,7 @@ func file_user_proto_init() {
|
|||
}
|
||||
}
|
||||
}
|
||||
file_user_proto_msgTypes[2].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
|
|
@ -24,4 +24,8 @@ message ServiceAccount {
|
|||
string user_id = 2;
|
||||
google.protobuf.Timestamp expires_at = 3;
|
||||
google.protobuf.Timestamp issued_at = 4;
|
||||
|
||||
optional string impersonate_user_id = 5;
|
||||
optional string impersonate_email = 6;
|
||||
repeated string impersonate_groups = 7;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,8 @@ func TestSignedJWT(t *testing.T) {
|
|||
grpc.StreamInterceptor(StreamRequireSignedJWT(base64.StdEncoding.EncodeToString(key))),
|
||||
grpc.UnaryInterceptor(UnaryRequireSignedJWT(base64.StdEncoding.EncodeToString(key))),
|
||||
)
|
||||
go srv.Serve(li)
|
||||
|
||||
reflection.Register(srv)
|
||||
go srv.Serve(li)
|
||||
|
||||
t.Run("unauthenticated", func(t *testing.T) {
|
||||
cc, err := grpc.Dial(li.Addr().String(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue