Пример #1
0
func TestMakeSplitUsername(t *testing.T) {
	username := serviceaccount.MakeUsername("ns", "name")
	ns, name, err := serviceaccount.SplitUsername(username)
	if err != nil {
		t.Errorf("Unexpected error %v", err)
	}
	if ns != "ns" || name != "name" {
		t.Errorf("Expected ns/name, got %s/%s", ns, name)
	}

	invalid := []string{"test", "system:serviceaccount", "system:serviceaccount:", "system:serviceaccount:ns", "system:serviceaccount:ns:name:extra"}
	for _, n := range invalid {
		_, _, err := serviceaccount.SplitUsername("test")
		if err == nil {
			t.Errorf("Expected error for %s", n)
		}
	}
}
Пример #2
0
func WithImpersonation(handler http.Handler, requestContextMapper api.RequestContextMapper, a authorizer.Authorizer) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		requestedSubject := req.Header.Get("Impersonate-User")
		if len(requestedSubject) == 0 {
			handler.ServeHTTP(w, req)
			return
		}

		ctx, exists := requestContextMapper.Get(req)
		if !exists {
			forbidden(w, req)
			return
		}
		requestor, exists := api.UserFrom(ctx)
		if !exists {
			forbidden(w, req)
			return
		}

		actingAsAttributes := &authorizer.AttributesRecord{
			User:            requestor,
			Verb:            "impersonate",
			APIGroup:        api.GroupName,
			Resource:        "users",
			Name:            requestedSubject,
			ResourceRequest: true,
		}
		if namespace, name, err := serviceaccount.SplitUsername(requestedSubject); err == nil {
			actingAsAttributes.Resource = "serviceaccounts"
			actingAsAttributes.Namespace = namespace
			actingAsAttributes.Name = name
		}

		err := a.Authorize(actingAsAttributes)
		if err != nil {
			forbidden(w, req)
			return
		}

		switch {
		case strings.HasPrefix(requestedSubject, serviceaccount.ServiceAccountUsernamePrefix):
			namespace, name, err := serviceaccount.SplitUsername(requestedSubject)
			if err != nil {
				forbidden(w, req)
				return
			}
			requestContextMapper.Update(req, api.WithUser(ctx, serviceaccount.UserInfo(namespace, name, "")))

		default:
			newUser := &user.DefaultInfo{
				Name: requestedSubject,
			}
			requestContextMapper.Update(req, api.WithUser(ctx, newUser))
		}

		newCtx, _ := requestContextMapper.Get(req)
		oldUser, _ := api.UserFrom(ctx)
		newUser, _ := api.UserFrom(newCtx)
		httplog.LogOf(req, w).Addf("%v is acting as %v", oldUser, newUser)

		handler.ServeHTTP(w, req)
	})
}