// InstallAPI registers endpoints for an OAuth2 server into the provided mux, // then returns an array of strings indicating what endpoints were started // (these are format strings that will expect to be sent a single string value). func (c *AuthConfig) InstallAPI(container *restful.Container) ([]string, error) { mux := c.getMux(container) clientStorage, err := clientetcd.NewREST(c.RESTOptionsGetter) if err != nil { return nil, err } clientRegistry := clientregistry.NewRegistry(clientStorage) combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(c.KubeClient, c.KubeClient, clientRegistry) accessTokenStorage, err := accesstokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter, c.EtcdBackends...) if err != nil { return nil, err } accessTokenRegistry := accesstokenregistry.NewRegistry(accessTokenStorage) authorizeTokenStorage, err := authorizetokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter, c.EtcdBackends...) if err != nil { return nil, err } authorizeTokenRegistry := authorizetokenregistry.NewRegistry(authorizeTokenStorage) clientAuthStorage, err := clientauthetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter) if err != nil { return nil, err } clientAuthRegistry := clientauthregistry.NewRegistry(clientAuthStorage) errorPageHandler, err := c.getErrorHandler() if err != nil { glog.Fatal(err) } authRequestHandler, authHandler, authFinalizer, err := c.getAuthorizeAuthenticationHandlers(mux, errorPageHandler) if err != nil { glog.Fatal(err) } storage := registrystorage.New(accessTokenRegistry, authorizeTokenRegistry, combinedOAuthClientGetter, registry.NewUserConversion()) config := osinserver.NewDefaultServerConfig() if c.Options.TokenConfig.AuthorizeTokenMaxAgeSeconds > 0 { config.AuthorizationExpiration = c.Options.TokenConfig.AuthorizeTokenMaxAgeSeconds } if c.Options.TokenConfig.AccessTokenMaxAgeSeconds > 0 { config.AccessExpiration = c.Options.TokenConfig.AccessTokenMaxAgeSeconds } grantChecker := registry.NewClientAuthorizationGrantChecker(clientAuthRegistry) grantHandler := c.getGrantHandler(mux, authRequestHandler, combinedOAuthClientGetter, clientAuthRegistry) server := osinserver.New( config, storage, osinserver.AuthorizeHandlers{ handlers.NewAuthorizeAuthenticator( authRequestHandler, authHandler, errorPageHandler, ), handlers.NewGrantCheck( grantChecker, grantHandler, errorPageHandler, ), authFinalizer, }, osinserver.AccessHandlers{ handlers.NewDenyAccessAuthenticator(), }, osinserver.NewDefaultErrorHandler(), ) server.Install(mux, OpenShiftOAuthAPIPrefix) if err := CreateOrUpdateDefaultOAuthClients(c.Options.MasterPublicURL, c.AssetPublicAddresses, clientRegistry); err != nil { glog.Fatal(err) } browserClient, err := clientRegistry.GetClient(kapi.NewContext(), OpenShiftBrowserClientID) if err != nil { glog.Fatal(err) } osOAuthClientConfig := c.NewOpenShiftOAuthClientConfig(browserClient) osOAuthClientConfig.RedirectUrl = c.Options.MasterPublicURL + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.DisplayTokenEndpoint) osOAuthClient, _ := osincli.NewClient(osOAuthClientConfig) if len(*c.Options.MasterCA) > 0 { rootCAs, err := cmdutil.CertPoolFromFile(*c.Options.MasterCA) if err != nil { glog.Fatal(err) } osOAuthClient.Transport = knet.SetTransportDefaults(&http.Transport{ TLSClientConfig: &tls.Config{RootCAs: rootCAs}, }) } tokenRequestEndpoints := tokenrequest.NewEndpoints(c.Options.MasterPublicURL, osOAuthClient) tokenRequestEndpoints.Install(mux, OpenShiftOAuthAPIPrefix) // glog.Infof("oauth server configured as: %#v", server) // glog.Infof("auth handler: %#v", authHandler) // glog.Infof("auth request handler: %#v", authRequestHandler) // glog.Infof("grant checker: %#v", grantChecker) // glog.Infof("grant handler: %#v", grantHandler) return []string{ fmt.Sprintf("Started OAuth2 API at %%s%s", OpenShiftOAuthAPIPrefix), }, nil }
func (c *MasterConfig) GetRestStorage() map[string]rest.Storage { defaultRegistry := env("OPENSHIFT_DEFAULT_REGISTRY", "${DOCKER_REGISTRY_SERVICE_HOST}:${DOCKER_REGISTRY_SERVICE_PORT}") svcCache := service.NewServiceResolverCache(c.KubeClient().Services(kapi.NamespaceDefault).Get) defaultRegistryFunc, err := svcCache.Defer(defaultRegistry) if err != nil { glog.Fatalf("OPENSHIFT_DEFAULT_REGISTRY variable is invalid %q: %v", defaultRegistry, err) } kubeletClient, err := kclient.NewKubeletClient(c.KubeletClientConfig) if err != nil { glog.Fatalf("Unable to configure Kubelet client: %v", err) } buildStorage := buildetcd.NewStorage(c.EtcdHelper) buildRegistry := buildregistry.NewRegistry(buildStorage) buildConfigStorage := buildconfigetcd.NewStorage(c.EtcdHelper) buildConfigRegistry := buildconfigregistry.NewRegistry(buildConfigStorage) deployConfigStorage := deployconfigetcd.NewStorage(c.EtcdHelper) deployConfigRegistry := deployconfigregistry.NewRegistry(deployConfigStorage) routeAllocator := c.RouteAllocator() routeEtcd := routeetcd.NewREST(c.EtcdHelper, routeAllocator) hostSubnetStorage := hostsubnetetcd.NewREST(c.EtcdHelper) netNamespaceStorage := netnamespaceetcd.NewREST(c.EtcdHelper) clusterNetworkStorage := clusternetworketcd.NewREST(c.EtcdHelper) userStorage := useretcd.NewREST(c.EtcdHelper) userRegistry := userregistry.NewRegistry(userStorage) identityStorage := identityetcd.NewREST(c.EtcdHelper) identityRegistry := identityregistry.NewRegistry(identityStorage) userIdentityMappingStorage := useridentitymapping.NewREST(userRegistry, identityRegistry) policyStorage := policyetcd.NewStorage(c.EtcdHelper) policyRegistry := policyregistry.NewRegistry(policyStorage) policyBindingStorage := policybindingetcd.NewStorage(c.EtcdHelper) policyBindingRegistry := policybindingregistry.NewRegistry(policyBindingStorage) clusterPolicyStorage := clusterpolicystorage.NewStorage(c.EtcdHelper) clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterPolicyStorage) clusterPolicyBindingStorage := clusterpolicybindingstorage.NewStorage(c.EtcdHelper) clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterPolicyBindingStorage) roleStorage := rolestorage.NewVirtualStorage(policyRegistry) roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry) clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry) clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry) subjectAccessReviewStorage := subjectaccessreview.NewREST(c.Authorizer) subjectAccessReviewRegistry := subjectaccessreview.NewRegistry(subjectAccessReviewStorage) localSubjectAccessReviewStorage := localsubjectaccessreview.NewREST(subjectAccessReviewRegistry) resourceAccessReviewStorage := resourceaccessreview.NewREST(c.Authorizer) resourceAccessReviewRegistry := resourceaccessreview.NewRegistry(resourceAccessReviewStorage) localResourceAccessReviewStorage := localresourceaccessreview.NewREST(resourceAccessReviewRegistry) imageStorage := imageetcd.NewREST(c.EtcdHelper) imageRegistry := image.NewRegistry(imageStorage) imageStreamStorage, imageStreamStatusStorage := imagestreametcd.NewREST(c.EtcdHelper, imagestream.DefaultRegistryFunc(defaultRegistryFunc), subjectAccessReviewRegistry) imageStreamRegistry := imagestream.NewRegistry(imageStreamStorage, imageStreamStatusStorage) imageStreamMappingStorage := imagestreammapping.NewREST(imageRegistry, imageStreamRegistry) imageStreamTagStorage := imagestreamtag.NewREST(imageRegistry, imageStreamRegistry) imageStreamTagRegistry := imagestreamtag.NewRegistry(imageStreamTagStorage) imageStreamImageStorage := imagestreamimage.NewREST(imageRegistry, imageStreamRegistry) imageStreamImageRegistry := imagestreamimage.NewRegistry(imageStreamImageStorage) buildGenerator := &buildgenerator.BuildGenerator{ Client: buildgenerator.Client{ GetBuildConfigFunc: buildConfigRegistry.GetBuildConfig, UpdateBuildConfigFunc: buildConfigRegistry.UpdateBuildConfig, GetBuildFunc: buildRegistry.GetBuild, CreateBuildFunc: buildRegistry.CreateBuild, GetImageStreamFunc: imageStreamRegistry.GetImageStream, GetImageStreamImageFunc: imageStreamImageRegistry.GetImageStreamImage, GetImageStreamTagFunc: imageStreamTagRegistry.GetImageStreamTag, }, ServiceAccounts: c.KubeClient(), Secrets: c.KubeClient(), } // TODO: with sharding, this needs to be changed deployConfigGenerator := &deployconfiggenerator.DeploymentConfigGenerator{ Client: deployconfiggenerator.Client{ DCFn: deployConfigRegistry.GetDeploymentConfig, ISFn: imageStreamRegistry.GetImageStream, LISFn2: imageStreamRegistry.ListImageStreams, }, } _, kclient := c.DeploymentConfigControllerClients() deployRollback := &deployrollback.RollbackGenerator{} deployRollbackClient := deployrollback.Client{ DCFn: deployConfigRegistry.GetDeploymentConfig, RCFn: clientDeploymentInterface{kclient}.GetDeployment, GRFn: deployRollback.GenerateRollback, } projectStorage := projectproxy.NewREST(kclient.Namespaces(), c.ProjectAuthorizationCache) namespace, templateName, err := configapi.ParseNamespaceAndName(c.Options.ProjectConfig.ProjectRequestTemplate) if err != nil { glog.Errorf("Error parsing project request template value: %v", err) // we can continue on, the storage that gets created will be valid, it simply won't work properly. There's no reason to kill the master } projectRequestStorage := projectrequeststorage.NewREST(c.Options.ProjectConfig.ProjectRequestMessage, namespace, templateName, c.PrivilegedLoopbackOpenShiftClient, c.PrivilegedLoopbackKubernetesClient) bcClient := c.BuildConfigWebHookClient() buildConfigWebHooks := buildconfigregistry.NewWebHookREST( buildConfigRegistry, buildclient.NewOSClientBuildConfigInstantiatorClient(bcClient), map[string]webhook.Plugin{ "generic": generic.New(), "github": github.New(), }, ) storage := map[string]rest.Storage{ "images": imageStorage, "imageStreams": imageStreamStorage, "imageStreams/status": imageStreamStatusStorage, "imageStreamImages": imageStreamImageStorage, "imageStreamMappings": imageStreamMappingStorage, "imageStreamTags": imageStreamTagStorage, "deploymentConfigs": deployConfigStorage, "generateDeploymentConfigs": deployconfiggenerator.NewREST(deployConfigGenerator, c.EtcdHelper.Codec()), "deploymentConfigRollbacks": deployrollback.NewREST(deployRollbackClient, c.EtcdHelper.Codec()), "processedTemplates": templateregistry.NewREST(), "templates": templateetcd.NewREST(c.EtcdHelper), "routes": routeEtcd.Route, "routes/status": routeEtcd.Status, "projects": projectStorage, "projectRequests": projectRequestStorage, "hostSubnets": hostSubnetStorage, "netNamespaces": netNamespaceStorage, "clusterNetworks": clusterNetworkStorage, "users": userStorage, "groups": groupetcd.NewREST(c.EtcdHelper), "identities": identityStorage, "userIdentityMappings": userIdentityMappingStorage, "oAuthAuthorizeTokens": authorizetokenetcd.NewREST(c.EtcdHelper), "oAuthAccessTokens": accesstokenetcd.NewREST(c.EtcdHelper), "oAuthClients": clientetcd.NewREST(c.EtcdHelper), "oAuthClientAuthorizations": clientauthetcd.NewREST(c.EtcdHelper), "resourceAccessReviews": resourceAccessReviewStorage, "subjectAccessReviews": subjectAccessReviewStorage, "localSubjectAccessReviews": localSubjectAccessReviewStorage, "localResourceAccessReviews": localResourceAccessReviewStorage, "policies": policyStorage, "policyBindings": policyBindingStorage, "roles": roleStorage, "roleBindings": roleBindingStorage, "clusterPolicies": clusterPolicyStorage, "clusterPolicyBindings": clusterPolicyBindingStorage, "clusterRoleBindings": clusterRoleBindingStorage, "clusterRoles": clusterRoleStorage, } if configapi.IsBuildEnabled(&c.Options) { storage["builds"] = buildStorage storage["buildConfigs"] = buildConfigStorage storage["buildConfigs/webhooks"] = buildConfigWebHooks storage["builds/clone"] = buildclonestorage.NewStorage(buildGenerator) storage["buildConfigs/instantiate"] = buildinstantiatestorage.NewStorage(buildGenerator) storage["builds/log"] = buildlogregistry.NewREST(buildRegistry, c.BuildLogClient(), kubeletClient) } return storage }
func (c *MasterConfig) GetRestStorage() map[string]rest.Storage { kubeletClient, err := kubeletclient.NewStaticKubeletClient(c.KubeletClientConfig) if err != nil { glog.Fatalf("Unable to configure Kubelet client: %v", err) } // TODO: allow the system CAs and the local CAs to be joined together. importTransport, err := restclient.TransportFor(&restclient.Config{}) if err != nil { glog.Fatalf("Unable to configure a default transport for importing: %v", err) } insecureImportTransport, err := restclient.TransportFor(&restclient.Config{Insecure: true}) if err != nil { glog.Fatalf("Unable to configure a default transport for importing: %v", err) } buildStorage, buildDetailsStorage, err := buildetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) buildRegistry := buildregistry.NewRegistry(buildStorage) buildConfigStorage, err := buildconfigetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) buildConfigRegistry := buildconfigregistry.NewRegistry(buildConfigStorage) deployConfigStorage, deployConfigStatusStorage, deployConfigScaleStorage, err := deployconfigetcd.NewREST(c.RESTOptionsGetter) dcInstantiateOriginClient, dcInstantiateKubeClient := c.DeploymentConfigInstantiateClients() dcInstantiateStorage := deployconfiginstantiate.NewREST( *deployConfigStorage.Store, dcInstantiateOriginClient, dcInstantiateKubeClient, c.ExternalVersionCodec, c.AdmissionControl, ) checkStorageErr(err) deployConfigRegistry := deployconfigregistry.NewRegistry(deployConfigStorage) routeAllocator := c.RouteAllocator() routeStorage, routeStatusStorage, err := routeetcd.NewREST(c.RESTOptionsGetter, routeAllocator) checkStorageErr(err) hostSubnetStorage, err := hostsubnetetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) netNamespaceStorage, err := netnamespaceetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) clusterNetworkStorage, err := clusternetworketcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) egressNetworkPolicyStorage, err := egressnetworkpolicyetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) userStorage, err := useretcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) userRegistry := userregistry.NewRegistry(userStorage) identityStorage, err := identityetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) identityRegistry := identityregistry.NewRegistry(identityStorage) userIdentityMappingStorage := useridentitymapping.NewREST(userRegistry, identityRegistry) groupStorage, err := groupetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) policyStorage, err := policyetcd.NewStorage(c.RESTOptionsGetter) checkStorageErr(err) policyRegistry := policyregistry.NewRegistry(policyStorage) policyBindingStorage, err := policybindingetcd.NewStorage(c.RESTOptionsGetter) checkStorageErr(err) policyBindingRegistry := policybindingregistry.NewRegistry(policyBindingStorage) clusterPolicyStorage, err := clusterpolicystorage.NewStorage(c.RESTOptionsGetter) checkStorageErr(err) clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterPolicyStorage) clusterPolicyBindingStorage, err := clusterpolicybindingstorage.NewStorage(c.RESTOptionsGetter) checkStorageErr(err) clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterPolicyBindingStorage) selfSubjectRulesReviewStorage := selfsubjectrulesreview.NewREST(c.RuleResolver, c.Informers.ClusterPolicies().Lister().ClusterPolicies()) subjectRulesReviewStorage := subjectrulesreview.NewREST(c.RuleResolver, c.Informers.ClusterPolicies().Lister().ClusterPolicies()) roleStorage := rolestorage.NewVirtualStorage(policyRegistry, c.RuleResolver) roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyBindingRegistry, c.RuleResolver) clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry) clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry) subjectAccessReviewStorage := subjectaccessreview.NewREST(c.Authorizer) subjectAccessReviewRegistry := subjectaccessreview.NewRegistry(subjectAccessReviewStorage) localSubjectAccessReviewStorage := localsubjectaccessreview.NewREST(subjectAccessReviewRegistry) resourceAccessReviewStorage := resourceaccessreview.NewREST(c.Authorizer) resourceAccessReviewRegistry := resourceaccessreview.NewRegistry(resourceAccessReviewStorage) localResourceAccessReviewStorage := localresourceaccessreview.NewREST(resourceAccessReviewRegistry) podSecurityPolicyReviewStorage := podsecuritypolicyreview.NewREST(oscc.NewDefaultSCCMatcher(c.Informers.SecurityContextConstraints().Lister()), clientadapter.FromUnversionedClient(c.PrivilegedLoopbackKubernetesClient)) podSecurityPolicySubjectStorage := podsecuritypolicysubjectreview.NewREST(oscc.NewDefaultSCCMatcher(c.Informers.SecurityContextConstraints().Lister()), clientadapter.FromUnversionedClient(c.PrivilegedLoopbackKubernetesClient)) podSecurityPolicySelfSubjectReviewStorage := podsecuritypolicyselfsubjectreview.NewREST(oscc.NewDefaultSCCMatcher(c.Informers.SecurityContextConstraints().Lister()), clientadapter.FromUnversionedClient(c.PrivilegedLoopbackKubernetesClient)) imageStorage, err := imageetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) imageRegistry := image.NewRegistry(imageStorage) imageSignatureStorage := imagesignature.NewREST(c.PrivilegedLoopbackOpenShiftClient.Images()) imageStreamSecretsStorage := imagesecret.NewREST(c.ImageStreamSecretClient()) imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage, err := imagestreametcd.NewREST(c.RESTOptionsGetter, c.RegistryNameFn, subjectAccessReviewRegistry, c.LimitVerifier) checkStorageErr(err) imageStreamRegistry := imagestream.NewRegistry(imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage) imageStreamMappingStorage := imagestreammapping.NewREST(imageRegistry, imageStreamRegistry, c.RegistryNameFn) imageStreamTagStorage := imagestreamtag.NewREST(imageRegistry, imageStreamRegistry) imageStreamTagRegistry := imagestreamtag.NewRegistry(imageStreamTagStorage) importerFn := func(r importer.RepositoryRetriever) imageimporter.Interface { return imageimporter.NewImageStreamImporter(r, c.Options.ImagePolicyConfig.MaxImagesBulkImportedPerRepository, flowcontrol.NewTokenBucketRateLimiter(2.0, 3)) } importerDockerClientFn := func() dockerregistry.Client { return dockerregistry.NewClient(20*time.Second, false) } imageStreamImportStorage := imagestreamimport.NewREST(importerFn, imageStreamRegistry, internalImageStreamStorage, imageStorage, c.ImageStreamImportSecretClient(), importTransport, insecureImportTransport, importerDockerClientFn) imageStreamImageStorage := imagestreamimage.NewREST(imageRegistry, imageStreamRegistry) imageStreamImageRegistry := imagestreamimage.NewRegistry(imageStreamImageStorage) buildGenerator := &buildgenerator.BuildGenerator{ Client: buildgenerator.Client{ GetBuildConfigFunc: buildConfigRegistry.GetBuildConfig, UpdateBuildConfigFunc: buildConfigRegistry.UpdateBuildConfig, GetBuildFunc: buildRegistry.GetBuild, CreateBuildFunc: buildRegistry.CreateBuild, GetImageStreamFunc: imageStreamRegistry.GetImageStream, GetImageStreamImageFunc: imageStreamImageRegistry.GetImageStreamImage, GetImageStreamTagFunc: imageStreamTagRegistry.GetImageStreamTag, }, ServiceAccounts: c.KubeClient(), Secrets: c.KubeClient(), } // TODO: with sharding, this needs to be changed deployConfigGenerator := &deployconfiggenerator.DeploymentConfigGenerator{ Client: deployconfiggenerator.Client{ DCFn: deployConfigRegistry.GetDeploymentConfig, ISFn: imageStreamRegistry.GetImageStream, LISFn2: imageStreamRegistry.ListImageStreams, }, } configClient, kclient := c.DeploymentConfigClients() deployRollbackClient := deployrollback.Client{ DCFn: deployConfigRegistry.GetDeploymentConfig, RCFn: clientDeploymentInterface{kclient}.GetDeployment, GRFn: deployrollback.NewRollbackGenerator().GenerateRollback, } deployConfigRollbackStorage := deployrollback.NewREST(configClient, kclient, c.ExternalVersionCodec) projectStorage := projectproxy.NewREST(c.PrivilegedLoopbackKubernetesClient.Namespaces(), c.ProjectAuthorizationCache, c.ProjectAuthorizationCache, c.ProjectCache) namespace, templateName, err := configapi.ParseNamespaceAndName(c.Options.ProjectConfig.ProjectRequestTemplate) if err != nil { glog.Errorf("Error parsing project request template value: %v", err) // we can continue on, the storage that gets created will be valid, it simply won't work properly. There's no reason to kill the master } projectRequestStorage := projectrequeststorage.NewREST(c.Options.ProjectConfig.ProjectRequestMessage, namespace, templateName, c.PrivilegedLoopbackOpenShiftClient, c.PrivilegedLoopbackKubernetesClient, c.Informers.PolicyBindings().Lister()) bcClient := c.BuildConfigWebHookClient() buildConfigWebHooks := buildconfigregistry.NewWebHookREST( buildConfigRegistry, buildclient.NewOSClientBuildConfigInstantiatorClient(bcClient), map[string]webhook.Plugin{ "generic": generic.New(), "github": github.New(), }, ) clientStorage, err := clientetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) clientRegistry := clientregistry.NewRegistry(clientStorage) // If OAuth is disabled, set the strategy to Deny saAccountGrantMethod := oauthapi.GrantHandlerDeny if c.Options.OAuthConfig != nil { // Otherwise, take the value provided in master-config.yaml saAccountGrantMethod = oauthapi.GrantHandlerType(c.Options.OAuthConfig.GrantConfig.ServiceAccountMethod) } combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(c.KubeClient(), c.KubeClient(), clientRegistry, saAccountGrantMethod) authorizeTokenStorage, err := authorizetokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter) checkStorageErr(err) accessTokenStorage, err := accesstokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter) checkStorageErr(err) clientAuthorizationStorage, err := clientauthetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter) checkStorageErr(err) templateStorage, err := templateetcd.NewREST(c.RESTOptionsGetter) checkStorageErr(err) storage := map[string]rest.Storage{ "images": imageStorage, "imagesignatures": imageSignatureStorage, "imageStreams/secrets": imageStreamSecretsStorage, "imageStreams": imageStreamStorage, "imageStreams/status": imageStreamStatusStorage, "imageStreamImports": imageStreamImportStorage, "imageStreamImages": imageStreamImageStorage, "imageStreamMappings": imageStreamMappingStorage, "imageStreamTags": imageStreamTagStorage, "deploymentConfigs": deployConfigStorage, "deploymentConfigs/scale": deployConfigScaleStorage, "deploymentConfigs/status": deployConfigStatusStorage, "deploymentConfigs/rollback": deployConfigRollbackStorage, "deploymentConfigs/log": deploylogregistry.NewREST(configClient, kclient, c.DeploymentLogClient(), kubeletClient), "deploymentConfigs/instantiate": dcInstantiateStorage, // TODO: Deprecate these "generateDeploymentConfigs": deployconfiggenerator.NewREST(deployConfigGenerator, c.ExternalVersionCodec), "deploymentConfigRollbacks": deployrollback.NewDeprecatedREST(deployRollbackClient, c.ExternalVersionCodec), "processedTemplates": templateregistry.NewREST(), "templates": templateStorage, "routes": routeStorage, "routes/status": routeStatusStorage, "projects": projectStorage, "projectRequests": projectRequestStorage, "hostSubnets": hostSubnetStorage, "netNamespaces": netNamespaceStorage, "clusterNetworks": clusterNetworkStorage, "egressNetworkPolicies": egressNetworkPolicyStorage, "users": userStorage, "groups": groupStorage, "identities": identityStorage, "userIdentityMappings": userIdentityMappingStorage, "oAuthAuthorizeTokens": authorizeTokenStorage, "oAuthAccessTokens": accessTokenStorage, "oAuthClients": clientStorage, "oAuthClientAuthorizations": clientAuthorizationStorage, "resourceAccessReviews": resourceAccessReviewStorage, "subjectAccessReviews": subjectAccessReviewStorage, "localSubjectAccessReviews": localSubjectAccessReviewStorage, "localResourceAccessReviews": localResourceAccessReviewStorage, "selfSubjectRulesReviews": selfSubjectRulesReviewStorage, "subjectRulesReviews": subjectRulesReviewStorage, "podSecurityPolicyReviews": podSecurityPolicyReviewStorage, "podSecurityPolicySubjectReviews": podSecurityPolicySubjectStorage, "podSecurityPolicySelfSubjectReviews": podSecurityPolicySelfSubjectReviewStorage, "policies": policyStorage, "policyBindings": policyBindingStorage, "roles": roleStorage, "roleBindings": roleBindingStorage, "clusterPolicies": clusterPolicyStorage, "clusterPolicyBindings": clusterPolicyBindingStorage, "clusterRoleBindings": clusterRoleBindingStorage, "clusterRoles": clusterRoleStorage, "clusterResourceQuotas": restInPeace(clusterresourcequotaregistry.NewStorage(c.RESTOptionsGetter)), "clusterResourceQuotas/status": updateInPeace(clusterresourcequotaregistry.NewStatusStorage(c.RESTOptionsGetter)), "appliedClusterResourceQuotas": appliedclusterresourcequotaregistry.NewREST( c.ClusterQuotaMappingController.GetClusterQuotaMapper(), c.Informers.ClusterResourceQuotas().Lister(), c.Informers.Namespaces().Lister()), } if configapi.IsBuildEnabled(&c.Options) { storage["builds"] = buildStorage storage["buildConfigs"] = buildConfigStorage storage["buildConfigs/webhooks"] = buildConfigWebHooks storage["builds/clone"] = buildclone.NewStorage(buildGenerator) storage["buildConfigs/instantiate"] = buildconfiginstantiate.NewStorage(buildGenerator) storage["buildConfigs/instantiatebinary"] = buildconfiginstantiate.NewBinaryStorage(buildGenerator, buildStorage, c.BuildLogClient(), kubeletClient) storage["builds/log"] = buildlogregistry.NewREST(buildStorage, buildStorage, c.BuildLogClient(), kubeletClient) storage["builds/details"] = buildDetailsStorage } return storage }
func TestCLIGetToken(t *testing.T) { testutil.DeleteAllEtcdKeys() // setup etcdClient := testutil.NewEtcdClient() etcdHelper, _ := master.NewEtcdStorage(etcdClient, latest.InterfacesFor, latest.Version, etcdtest.PathPrefix()) accessTokenStorage := accesstokenetcd.NewREST(etcdHelper) accessTokenRegistry := accesstokenregistry.NewRegistry(accessTokenStorage) authorizeTokenStorage := authorizetokenetcd.NewREST(etcdHelper) authorizeTokenRegistry := authorizetokenregistry.NewRegistry(authorizeTokenStorage) clientStorage := clientetcd.NewREST(etcdHelper) clientRegistry := clientregistry.NewRegistry(clientStorage) clientAuthStorage := clientauthetcd.NewREST(etcdHelper) clientAuthRegistry := clientauthregistry.NewRegistry(clientAuthStorage) userStorage := useretcd.NewREST(etcdHelper) userRegistry := userregistry.NewRegistry(userStorage) identityStorage := identityetcd.NewREST(etcdHelper) identityRegistry := identityregistry.NewRegistry(identityStorage) identityMapper := identitymapper.NewAlwaysCreateUserIdentityToUserMapper(identityRegistry, userRegistry) authRequestHandler := basicauthrequest.NewBasicAuthAuthentication(allowanypassword.New("get-token-test", identityMapper), true) authHandler := oauthhandlers.NewUnionAuthenticationHandler( map[string]oauthhandlers.AuthenticationChallenger{"login": passwordchallenger.NewBasicAuthChallenger("openshift")}, nil, nil) storage := registrystorage.New(accessTokenRegistry, authorizeTokenRegistry, clientRegistry, oauthregistry.NewUserConversion()) config := osinserver.NewDefaultServerConfig() grantChecker := oauthregistry.NewClientAuthorizationGrantChecker(clientAuthRegistry) grantHandler := oauthhandlers.NewAutoGrant() server := osinserver.New( config, storage, osinserver.AuthorizeHandlers{ oauthhandlers.NewAuthorizeAuthenticator( authRequestHandler, authHandler, oauthhandlers.EmptyError{}, ), oauthhandlers.NewGrantCheck( grantChecker, grantHandler, oauthhandlers.EmptyError{}, ), }, osinserver.AccessHandlers{ oauthhandlers.NewDenyAccessAuthenticator(), }, osinserver.NewDefaultErrorHandler(), ) mux := http.NewServeMux() server.Install(mux, origin.OpenShiftOAuthAPIPrefix) oauthServer := httptest.NewServer(http.Handler(mux)) defer oauthServer.Close() t.Logf("oauth server is on %v\n", oauthServer.URL) // create the default oauth clients with redirects to our server origin.CreateOrUpdateDefaultOAuthClients(oauthServer.URL, []string{oauthServer.URL}, clientRegistry) flags := pflag.NewFlagSet("test-flags", pflag.ContinueOnError) clientCfg := clientcmd.NewConfig() clientCfg.Bind(flags) flags.Parse(strings.Split("--master="+oauthServer.URL, " ")) reader := bytes.NewBufferString("user\npass") accessToken, err := tokencmd.RequestToken(clientCfg.OpenShiftConfig(), reader, "", "") if err != nil { t.Errorf("Unexpected error: %v", err) } if len(accessToken) == 0 { t.Error("Expected accessToken, but did not get one") } // lets see if this access token is any good token, err := accessTokenRegistry.GetAccessToken(kapi.NewContext(), accessToken) if err != nil { t.Errorf("Unexpected error: %v", err) } if token.UserName != "user" { t.Errorf("Expected token for \"user\", but got: %#v", token) } }
func (c *MasterConfig) GetRestStorage() map[string]rest.Storage { defaultRegistry := env("OPENSHIFT_DEFAULT_REGISTRY", "${DOCKER_REGISTRY_SERVICE_HOST}:${DOCKER_REGISTRY_SERVICE_PORT}") svcCache := service.NewServiceResolverCache(c.KubeClient().Services(kapi.NamespaceDefault).Get) defaultRegistryFunc, err := svcCache.Defer(defaultRegistry) if err != nil { glog.Fatalf("OPENSHIFT_DEFAULT_REGISTRY variable is invalid %q: %v", defaultRegistry, err) } kubeletClient, err := kubeletclient.NewStaticKubeletClient(c.KubeletClientConfig) if err != nil { glog.Fatalf("Unable to configure Kubelet client: %v", err) } // TODO: allow the system CAs and the local CAs to be joined together. importTransport, err := restclient.TransportFor(&restclient.Config{}) if err != nil { glog.Fatalf("Unable to configure a default transport for importing: %v", err) } insecureImportTransport, err := restclient.TransportFor(&restclient.Config{Insecure: true}) if err != nil { glog.Fatalf("Unable to configure a default transport for importing: %v", err) } applicationStorage := application.NewREST(c.EtcdHelper, c.PrivilegedLoopbackOpenShiftClient, c.PrivilegedLoopbackKubernetesClient) serviceBrokerStorage := servicebroker.NewREST(c.EtcdHelper, c.BackingServiceInstanceControllerClients()) backingServiceStorage := backingservice.NewREST(c.EtcdHelper, c.BackingServiceInstanceControllerClients()) buildStorage, buildDetailsStorage := buildetcd.NewREST(c.EtcdHelper) buildRegistry := buildregistry.NewRegistry(buildStorage) buildConfigStorage := buildconfigetcd.NewREST(c.EtcdHelper) buildConfigRegistry := buildconfigregistry.NewRegistry(buildConfigStorage) deployConfigStorage, deployConfigScaleStorage := deployconfigetcd.NewREST(c.EtcdHelper, c.DeploymentConfigScaleClient()) deployConfigRegistry := deployconfigregistry.NewRegistry(deployConfigStorage) routeAllocator := c.RouteAllocator() routeStorage, routeStatusStorage := routeetcd.NewREST(c.EtcdHelper, routeAllocator) hostSubnetStorage := hostsubnetetcd.NewREST(c.EtcdHelper) netNamespaceStorage := netnamespaceetcd.NewREST(c.EtcdHelper) clusterNetworkStorage := clusternetworketcd.NewREST(c.EtcdHelper) userStorage := useretcd.NewREST(c.EtcdHelper) userRegistry := userregistry.NewRegistry(userStorage) identityStorage := identityetcd.NewREST(c.EtcdHelper) identityRegistry := identityregistry.NewRegistry(identityStorage) userIdentityMappingStorage := useridentitymapping.NewREST(userRegistry, identityRegistry) policyStorage := policyetcd.NewStorage(c.EtcdHelper) policyRegistry := policyregistry.NewRegistry(policyStorage) policyBindingStorage := policybindingetcd.NewStorage(c.EtcdHelper) policyBindingRegistry := policybindingregistry.NewRegistry(policyBindingStorage) clusterPolicyStorage := clusterpolicystorage.NewStorage(c.EtcdHelper) clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterPolicyStorage) clusterPolicyBindingStorage := clusterpolicybindingstorage.NewStorage(c.EtcdHelper) clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterPolicyBindingStorage) ruleResolver := rulevalidation.NewDefaultRuleResolver( policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry, ) roleStorage := rolestorage.NewVirtualStorage(policyRegistry, ruleResolver) roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyBindingRegistry, ruleResolver) clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry) clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry) subjectAccessReviewStorage := subjectaccessreview.NewREST(c.Authorizer) subjectAccessReviewRegistry := subjectaccessreview.NewRegistry(subjectAccessReviewStorage) localSubjectAccessReviewStorage := localsubjectaccessreview.NewREST(subjectAccessReviewRegistry) resourceAccessReviewStorage := resourceaccessreview.NewREST(c.Authorizer) resourceAccessReviewRegistry := resourceaccessreview.NewRegistry(resourceAccessReviewStorage) localResourceAccessReviewStorage := localresourceaccessreview.NewREST(resourceAccessReviewRegistry) imageStorage := imageetcd.NewREST(c.EtcdHelper) imageRegistry := image.NewRegistry(imageStorage) imageStreamSecretsStorage := imagesecret.NewREST(c.ImageStreamSecretClient()) imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage := imagestreametcd.NewREST(c.EtcdHelper, imagestream.DefaultRegistryFunc(defaultRegistryFunc), subjectAccessReviewRegistry) imageStreamRegistry := imagestream.NewRegistry(imageStreamStorage, imageStreamStatusStorage, internalImageStreamStorage) imageStreamMappingStorage := imagestreammapping.NewREST(imageRegistry, imageStreamRegistry) imageStreamTagStorage := imagestreamtag.NewREST(imageRegistry, imageStreamRegistry) imageStreamTagRegistry := imagestreamtag.NewRegistry(imageStreamTagStorage) importerFn := func(r importer.RepositoryRetriever) imageimporter.Interface { return imageimporter.NewImageStreamImporter(r, c.Options.ImagePolicyConfig.MaxImagesBulkImportedPerRepository, util.NewTokenBucketRateLimiter(2.0, 3)) } importerDockerClientFn := func() dockerregistry.Client { return dockerregistry.NewClient(20*time.Second, false) } imageStreamImportStorage := imagestreamimport.NewREST(importerFn, imageStreamRegistry, internalImageStreamStorage, imageStorage, c.ImageStreamImportSecretClient(), importTransport, insecureImportTransport, importerDockerClientFn) imageStreamImageStorage := imagestreamimage.NewREST(imageRegistry, imageStreamRegistry) imageStreamImageRegistry := imagestreamimage.NewRegistry(imageStreamImageStorage) backingServiceInstanceEtcd := backingserviceinstanceetcd.NewREST(c.EtcdHelper) backingServiceInstanceRegistry := backingserviceinstanceregistry.NewRegistry(backingServiceInstanceEtcd) backingServiceInstanceBindingEtcd := backingserviceinstanceetcd.NewBindingREST(backingServiceInstanceRegistry, deployConfigRegistry) buildGenerator := &buildgenerator.BuildGenerator{ Client: buildgenerator.Client{ GetBuildConfigFunc: buildConfigRegistry.GetBuildConfig, UpdateBuildConfigFunc: buildConfigRegistry.UpdateBuildConfig, GetBuildFunc: buildRegistry.GetBuild, CreateBuildFunc: buildRegistry.CreateBuild, GetImageStreamFunc: imageStreamRegistry.GetImageStream, GetImageStreamImageFunc: imageStreamImageRegistry.GetImageStreamImage, GetImageStreamTagFunc: imageStreamTagRegistry.GetImageStreamTag, }, ServiceAccounts: c.KubeClient(), Secrets: c.KubeClient(), } // TODO: with sharding, this needs to be changed deployConfigGenerator := &deployconfiggenerator.DeploymentConfigGenerator{ Client: deployconfiggenerator.Client{ DCFn: deployConfigRegistry.GetDeploymentConfig, ISFn: imageStreamRegistry.GetImageStream, LISFn2: imageStreamRegistry.ListImageStreams, }, } configClient, kclient := c.DeploymentConfigClients() deployRollback := &deployrollback.RollbackGenerator{} deployRollbackClient := deployrollback.Client{ DCFn: deployConfigRegistry.GetDeploymentConfig, RCFn: clientDeploymentInterface{kclient}.GetDeployment, GRFn: deployRollback.GenerateRollback, } projectStorage := projectproxy.NewREST(kclient.Namespaces(), c.ProjectAuthorizationCache) namespace, templateName, err := configapi.ParseNamespaceAndName(c.Options.ProjectConfig.ProjectRequestTemplate) if err != nil { glog.Errorf("Error parsing project request template value: %v", err) // we can continue on, the storage that gets created will be valid, it simply won't work properly. There's no reason to kill the master } projectRequestStorage := projectrequeststorage.NewREST(c.Options.ProjectConfig.ProjectRequestMessage, namespace, templateName, c.PrivilegedLoopbackOpenShiftClient, c.PrivilegedLoopbackKubernetesClient) bcClient := c.BuildConfigWebHookClient() buildConfigWebHooks := buildconfigregistry.NewWebHookREST( buildConfigRegistry, buildclient.NewOSClientBuildConfigInstantiatorClient(bcClient), map[string]webhook.Plugin{ "generic": generic.New(), "github": github.New(), }, ) storage := map[string]rest.Storage{ "images": imageStorage, "imageStreams/secrets": imageStreamSecretsStorage, "imageStreams": imageStreamStorage, "imageStreams/status": imageStreamStatusStorage, "imageStreamImports": imageStreamImportStorage, "imageStreamImages": imageStreamImageStorage, "imageStreamMappings": imageStreamMappingStorage, "imageStreamTags": imageStreamTagStorage, "applications": applicationStorage, "serviceBrokers": serviceBrokerStorage, "backingServices": backingServiceStorage, "backingServiceInstances": backingServiceInstanceEtcd, "backingServiceInstances/binding": backingServiceInstanceBindingEtcd, "deploymentConfigs": deployConfigStorage, "deploymentConfigs/scale": deployConfigScaleStorage, "generateDeploymentConfigs": deployconfiggenerator.NewREST(deployConfigGenerator, c.EtcdHelper.Codec()), "deploymentConfigRollbacks": deployrollback.NewREST(deployRollbackClient, c.EtcdHelper.Codec()), "deploymentConfigs/log": deploylogregistry.NewREST(configClient, kclient, c.DeploymentLogClient(), kubeletClient), "processedTemplates": templateregistry.NewREST(), "templates": templateetcd.NewREST(c.EtcdHelper), "routes": routeStorage, "routes/status": routeStatusStorage, "projects": projectStorage, "projectRequests": projectRequestStorage, "hostSubnets": hostSubnetStorage, "netNamespaces": netNamespaceStorage, "clusterNetworks": clusterNetworkStorage, "users": userStorage, "groups": groupetcd.NewREST(c.EtcdHelper), "identities": identityStorage, "userIdentityMappings": userIdentityMappingStorage, "oAuthAuthorizeTokens": authorizetokenetcd.NewREST(c.EtcdHelper), "oAuthAccessTokens": accesstokenetcd.NewREST(c.EtcdHelper), "oAuthClients": clientetcd.NewREST(c.EtcdHelper), "oAuthClientAuthorizations": clientauthetcd.NewREST(c.EtcdHelper), "resourceAccessReviews": resourceAccessReviewStorage, "subjectAccessReviews": subjectAccessReviewStorage, "localSubjectAccessReviews": localSubjectAccessReviewStorage, "localResourceAccessReviews": localResourceAccessReviewStorage, "policies": policyStorage, "policyBindings": policyBindingStorage, "roles": roleStorage, "roleBindings": roleBindingStorage, "clusterPolicies": clusterPolicyStorage, "clusterPolicyBindings": clusterPolicyBindingStorage, "clusterRoleBindings": clusterRoleBindingStorage, "clusterRoles": clusterRoleStorage, } if configapi.IsBuildEnabled(&c.Options) { storage["builds"] = buildStorage storage["buildConfigs"] = buildConfigStorage storage["buildConfigs/webhooks"] = buildConfigWebHooks storage["builds/clone"] = buildclone.NewStorage(buildGenerator) storage["buildConfigs/instantiate"] = buildconfiginstantiate.NewStorage(buildGenerator) storage["buildConfigs/instantiatebinary"] = buildconfiginstantiate.NewBinaryStorage(buildGenerator, buildStorage, c.BuildLogClient(), kubeletClient) storage["builds/log"] = buildlogregistry.NewREST(buildStorage, buildStorage, c.BuildLogClient(), kubeletClient) storage["builds/details"] = buildDetailsStorage } return storage }
// InstallAPI registers endpoints for an OAuth2 server into the provided mux, // then returns an array of strings indicating what endpoints were started // (these are format strings that will expect to be sent a single string value). func (c *AuthConfig) InstallAPI(container *restful.Container) []string { // TODO: register into container mux := container.ServeMux accessTokenStorage := accesstokenetcd.NewREST(c.EtcdHelper) accessTokenRegistry := accesstokenregistry.NewRegistry(accessTokenStorage) authorizeTokenStorage := authorizetokenetcd.NewREST(c.EtcdHelper) authorizeTokenRegistry := authorizetokenregistry.NewRegistry(authorizeTokenStorage) clientStorage := clientetcd.NewREST(c.EtcdHelper) clientRegistry := clientregistry.NewRegistry(clientStorage) clientAuthStorage := clientauthetcd.NewREST(c.EtcdHelper) clientAuthRegistry := clientauthregistry.NewRegistry(clientAuthStorage) authRequestHandler, authHandler, authFinalizer, err := c.getAuthorizeAuthenticationHandlers(mux) if err != nil { glog.Fatal(err) } storage := registrystorage.New(accessTokenRegistry, authorizeTokenRegistry, clientRegistry, registry.NewUserConversion()) config := osinserver.NewDefaultServerConfig() if c.Options.TokenConfig.AuthorizeTokenMaxAgeSeconds > 0 { config.AuthorizationExpiration = c.Options.TokenConfig.AuthorizeTokenMaxAgeSeconds } if c.Options.TokenConfig.AccessTokenMaxAgeSeconds > 0 { config.AccessExpiration = c.Options.TokenConfig.AccessTokenMaxAgeSeconds } grantChecker := registry.NewClientAuthorizationGrantChecker(clientAuthRegistry) grantHandler := c.getGrantHandler(mux, authRequestHandler, clientRegistry, clientAuthRegistry) server := osinserver.New( config, storage, osinserver.AuthorizeHandlers{ handlers.NewAuthorizeAuthenticator( authRequestHandler, authHandler, handlers.EmptyError{}, ), handlers.NewGrantCheck( grantChecker, grantHandler, handlers.EmptyError{}, ), authFinalizer, }, osinserver.AccessHandlers{ handlers.NewDenyAccessAuthenticator(), }, osinserver.NewDefaultErrorHandler(), ) server.Install(mux, OpenShiftOAuthAPIPrefix) CreateOrUpdateDefaultOAuthClients(c.Options.MasterPublicURL, c.AssetPublicAddresses, clientRegistry) osOAuthClientConfig := c.NewOpenShiftOAuthClientConfig(&OSBrowserClientBase) osOAuthClientConfig.RedirectUrl = c.Options.MasterPublicURL + path.Join(OpenShiftOAuthAPIPrefix, tokenrequest.DisplayTokenEndpoint) osOAuthClient, _ := osincli.NewClient(osOAuthClientConfig) if len(*c.Options.MasterCA) > 0 { rootCAs, err := cmdutil.CertPoolFromFile(*c.Options.MasterCA) if err != nil { glog.Fatal(err) } osOAuthClient.Transport = kutil.SetTransportDefaults(&http.Transport{ TLSClientConfig: &tls.Config{RootCAs: rootCAs}, }) } tokenRequestEndpoints := tokenrequest.NewEndpoints(c.Options.MasterPublicURL, osOAuthClient) tokenRequestEndpoints.Install(mux, OpenShiftOAuthAPIPrefix) // glog.Infof("oauth server configured as: %#v", server) // glog.Infof("auth handler: %#v", authHandler) // glog.Infof("auth request handler: %#v", authRequestHandler) // glog.Infof("grant checker: %#v", grantChecker) // glog.Infof("grant handler: %#v", grantHandler) return []string{ fmt.Sprintf("Started OAuth2 API at %%s%s", OpenShiftOAuthAPIPrefix), fmt.Sprintf("Started Login endpoint at %%s%s", OpenShiftLoginPrefix), } }
func TestAuthProxyOnAuthorize(t *testing.T) { testutil.DeleteAllEtcdKeys() // setup etcdClient := testutil.NewEtcdClient() etcdHelper, _ := master.NewEtcdStorage(etcdClient, latest.InterfacesFor, latest.Version, etcdtest.PathPrefix()) accessTokenStorage := accesstokenetcd.NewREST(etcdHelper) accessTokenRegistry := accesstokenregistry.NewRegistry(accessTokenStorage) authorizeTokenStorage := authorizetokenetcd.NewREST(etcdHelper) authorizeTokenRegistry := authorizetokenregistry.NewRegistry(authorizeTokenStorage) clientStorage := clientetcd.NewREST(etcdHelper) clientRegistry := clientregistry.NewRegistry(clientStorage) clientAuthStorage := clientauthetcd.NewREST(etcdHelper) clientAuthRegistry := clientauthregistry.NewRegistry(clientAuthStorage) userStorage := useretcd.NewREST(etcdHelper) userRegistry := userregistry.NewRegistry(userStorage) identityStorage := identityetcd.NewREST(etcdHelper) identityRegistry := identityregistry.NewRegistry(identityStorage) identityMapper := identitymapper.NewAlwaysCreateUserIdentityToUserMapper(identityRegistry, userRegistry) // this auth request handler is the one that is supposed to recognize information from a front proxy authRequestHandler := headerrequest.NewAuthenticator("front-proxy-test", headerrequest.NewDefaultConfig(), identityMapper) authHandler := &oauthhandlers.EmptyAuth{} storage := registrystorage.New(accessTokenRegistry, authorizeTokenRegistry, clientRegistry, oauthregistry.NewUserConversion()) config := osinserver.NewDefaultServerConfig() grantChecker := oauthregistry.NewClientAuthorizationGrantChecker(clientAuthRegistry) grantHandler := oauthhandlers.NewAutoGrant() server := osinserver.New( config, storage, osinserver.AuthorizeHandlers{ oauthhandlers.NewAuthorizeAuthenticator( authRequestHandler, authHandler, oauthhandlers.EmptyError{}, ), oauthhandlers.NewGrantCheck( grantChecker, grantHandler, oauthhandlers.EmptyError{}, ), }, osinserver.AccessHandlers{ oauthhandlers.NewDenyAccessAuthenticator(), }, osinserver.NewDefaultErrorHandler(), ) mux := http.NewServeMux() server.Install(mux, origin.OpenShiftOAuthAPIPrefix) oauthServer := httptest.NewServer(http.Handler(mux)) defer oauthServer.Close() t.Logf("oauth server is on %v\n", oauthServer.URL) // set up a front proxy guarding the oauth server proxyHTTPHandler := NewBasicAuthChallenger("TestRegistryAndServer", validUsers, NewXRemoteUserProxyingHandler(oauthServer.URL)) proxyServer := httptest.NewServer(proxyHTTPHandler) defer proxyServer.Close() t.Logf("proxy server is on %v\n", proxyServer.URL) // need to prime clients so that we can get back a code. the client must be valid createClient(t, clientRegistry, &oauthapi.OAuthClient{ObjectMeta: kapi.ObjectMeta{Name: "test"}, Secret: "secret", RedirectURIs: []string{oauthServer.URL}}) // our simple URL to get back a code. We want to go through the front proxy rawAuthorizeRequest := proxyServer.URL + origin.OpenShiftOAuthAPIPrefix + "/authorize?response_type=code&client_id=test" // the first request we make to the front proxy should challenge us for authentication info shouldBeAChallengeResponse, err := http.Get(rawAuthorizeRequest) if err != nil { t.Errorf("Unexpected error: %v", err) } if shouldBeAChallengeResponse.StatusCode != http.StatusUnauthorized { t.Errorf("Expected Unauthorized, but got %v", shouldBeAChallengeResponse.StatusCode) } // create an http.Client to make our next request. We need a custom Transport to authenticate us through our front proxy // and a custom CheckRedirect so that we can keep track of the redirect responses we're getting // OAuth requests a few redirects that we don't really care about checking, so this simpler than using a round tripper // and manually handling redirects and setting our auth information every time for the front proxy redirectedUrls := make([]url.URL, 10) httpClient := http.Client{ CheckRedirect: getRedirectMethod(t, &redirectedUrls), Transport: kclient.NewBasicAuthRoundTripper("sanefarmer", "who?", http.DefaultTransport), } // make our authorize request again, but this time our transport has properly set the auth info for the front proxy req, err := http.NewRequest("GET", rawAuthorizeRequest, nil) _, err = httpClient.Do(req) if err != nil { t.Errorf("Unexpected error: %v", err) } // check the last redirect and see if we got a code foundCode := "" if len(redirectedUrls) > 0 { foundCode = redirectedUrls[len(redirectedUrls)-1].Query().Get("code") } if len(foundCode) == 0 { t.Errorf("Did not find code in any redirect: %v", redirectedUrls) } else { t.Logf("Found code %v\n", foundCode) } }