//VerifyToken verifies keystone v3.0 token func (client *keystoneV3Client) VerifyToken(token string) (schema.Authorization, error) { tokenResult := v3tokens.Get(client.client, token) _, err := tokenResult.Extract() if err != nil { return nil, fmt.Errorf("Invalid token") } tokenBody := tokenResult.Body.(map[string]interface{})["token"] roles := tokenBody.(map[string]interface{})["roles"] roleIDs := []string{} for _, roleBody := range roles.([]interface{}) { roleIDs = append(roleIDs, roleBody.(map[string]interface{})["name"].(string)) } tokenBodyMap := tokenBody.(map[string]interface{}) project := tokenBodyMap["project"].(map[string]interface{}) tenantID := project["id"].(string) tenantName := project["name"].(string) catalogList, ok := tokenBodyMap["catalog"].([]interface{}) catalogObj := []*schema.Catalog{} if ok { for _, rawCatalog := range catalogList { catalog := rawCatalog.(map[string]interface{}) endPoints := []*schema.Endpoint{} rawEndpoints, ok := catalog["endpoints"].([]interface{}) if ok { for _, rawEndpoint := range rawEndpoints { endpoint := rawEndpoint.(map[string]interface{}) endPoints = append(endPoints, schema.NewEndpoint(endpoint["url"].(string), endpoint["region"].(string), endpoint["interface"].(string))) } } catalogObj = append(catalogObj, schema.NewCatalog(catalog["name"].(string), catalog["type"].(string), endPoints)) } } return schema.NewAuthorization(tenantID, tenantName, token, roleIDs, catalogObj), nil }
func (env *Environment) addTestingAPI() { builtins := map[string]interface{}{ "Fail": func(call otto.FunctionCall) otto.Value { if len(call.ArgumentList) == 0 { panic(fmt.Errorf("Fail!")) } if !call.ArgumentList[0].IsString() { panic(fmt.Errorf("Invalid call to 'Fail': format string expected first")) } format, _ := call.ArgumentList[0].ToString() args := []interface{}{} for _, value := range call.ArgumentList[1:] { args = append(args, gohan_otto.ConvertOttoToGo(value)) } panic(fmt.Errorf(format, args...)) }, "MockTransaction": func(call otto.FunctionCall) otto.Value { newTransaction := false if len(call.ArgumentList) > 1 { panic("Wrong number of arguments in MockTransaction call.") } else if len(call.ArgumentList) == 1 { rawNewTransaction, _ := call.Argument(0).Export() newTransaction = rawNewTransaction.(bool) } transactionValue, _ := call.Otto.ToValue(env.getTransaction(newTransaction)) return transactionValue }, "CommitMockTransaction": func(call otto.FunctionCall) otto.Value { tx := env.getTransaction(false) tx.Commit() tx.Close() return otto.Value{} }, "MockPolicy": func(call otto.FunctionCall) otto.Value { policyValue, _ := call.Otto.ToValue(schema.NewEmptyPolicy()) return policyValue }, "MockAuthorization": func(call otto.FunctionCall) otto.Value { authorizationValue, _ := call.Otto.ToValue(schema.NewAuthorization("", "", "", []string{}, []*schema.Catalog{})) return authorizationValue }, } for name, object := range builtins { env.VM.Set(name, object) } // NOTE: There is no way to return error back to Otto after calling a Go // function, so the following function has to be written in pure JavaScript. env.VM.Otto.Run(`function GohanTrigger(event, context) { gohan_handle_event(event, context); }`) env.mockFunction("gohan_http") env.mockFunction("gohan_raw_http") env.mockFunction("gohan_db_transaction") env.mockFunction("gohan_config") }
//VerifyToken fake verify func (*FakeIdentity) VerifyToken(tokenID string) (schema.Authorization, error) { rawToken, ok := fakeTokens[tokenID] if !ok { return nil, fmt.Errorf("authentication error") } access, _ := rawToken.(map[string]interface{})["access"].(map[string]interface{}) tenantID := access["token"].(token).Tenant.ID tenantName := access["token"].(token).Tenant.Name role := access["user"].(map[string]interface{})["roles"].([]role)[0].Name return schema.NewAuthorization(tenantID, tenantName, tokenID, []string{role}, nil), nil }
//VerifyToken verifies keystone v2.0 token func (client *keystoneV2Client) VerifyToken(token string) (schema.Authorization, error) { tokenResult, err := verifyV2Token(client.client, token) if err != nil { return nil, fmt.Errorf("Invalid token") } fmt.Printf("%v", tokenResult) tokenBody := tokenResult.(map[string]interface{})["access"] userBody := tokenBody.(map[string]interface{})["user"] roles := userBody.(map[string]interface{})["roles"] roleIDs := []string{} for _, roleBody := range roles.([]interface{}) { roleIDs = append(roleIDs, roleBody.(map[string]interface{})["name"].(string)) } tokenBodyMap := tokenBody.(map[string]interface{}) tenantObj, ok := tokenBodyMap["token"].(map[string]interface{})["tenant"] if !ok { return nil, fmt.Errorf("Token is unscoped") } tenant := tenantObj.(map[string]interface{}) tenantID := tenant["id"].(string) tenantName := tenant["name"].(string) catalogList := tokenBodyMap["serviceCatalog"].([]interface{}) catalogObj := []*schema.Catalog{} for _, rawCatalog := range catalogList { catalog := rawCatalog.(map[string]interface{}) endPoints := []*schema.Endpoint{} rawEndpoints := catalog["endpoints"].([]interface{}) for _, rawEndpoint := range rawEndpoints { endpoint := rawEndpoint.(map[string]interface{}) region := endpoint["region"].(string) adminURL, ok := endpoint["adminURL"].(string) if ok { endPoints = append(endPoints, schema.NewEndpoint(adminURL, region, "admin")) } internalURL, ok := endpoint["internalURL"].(string) if ok { endPoints = append(endPoints, schema.NewEndpoint(internalURL, region, "internal")) } publicURL, ok := endpoint["publicURL"].(string) if ok { endPoints = append(endPoints, schema.NewEndpoint(publicURL, region, "public")) } } catalogObj = append(catalogObj, schema.NewCatalog(catalog["name"].(string), catalog["type"].(string), endPoints)) } return schema.NewAuthorization(tenantID, tenantName, token, roleIDs, catalogObj), nil }
//GetServiceAuthorization returns always authorization for admin func (i *NoIdentityService) GetServiceAuthorization() (schema.Authorization, error) { return schema.NewAuthorization("admin", "admin", "admin_token", []string{"admin"}, nil), nil }
context middleware.Context schemaID string path string action string currentSchema *schema.Schema extensions []*schema.Extension env extension.Environment events map[string]string network1 map[string]interface{} network2 map[string]interface{} subnet1 map[string]interface{} ) BeforeEach(func() { adminAuth = schema.NewAuthorization(adminTenantID, "admin", adminTokenID, []string{"admin"}, nil) memberAuth = schema.NewAuthorization(memberTenantID, "member", memberTokenID, []string{"_member_"}, nil) auth = adminAuth context = middleware.Context{} events = map[string]string{} network1 = map[string]interface{}{ "id": "test1", "name": "Rohan", "description": "The proud horsemasters", "tenant_id": adminTenantID, "providor_networks": map[string]interface{}{}, "route_targets": []interface{}{}, "shared": false,
//GetServiceAuthorization returns always authorization for nobody func (i *NobodyIdentityService) GetServiceAuthorization() (schema.Authorization, error) { return schema.NewAuthorization("nobody", "nobody", "nobody_token", []string{"Nobody"}, nil), nil }
//NewServer returns new GohanAPIServer func NewServer(configFile string) (*Server, error) { manager := schema.GetManager() config := util.GetConfig() err := config.ReadConfig(configFile) err = os.Chdir(path.Dir(configFile)) if err != nil { return nil, fmt.Errorf("Config load error: %s", err) } err = l.SetUpLogging(config) if err != nil { return nil, fmt.Errorf("Logging setup error: %s", err) } log.Info("logging initialized") server := &Server{} m := martini.Classic() m.Handlers() m.Use(middleware.Logging()) m.Use(martini.Recovery()) m.Use(middleware.JSONURLs()) m.Use(middleware.WithContext()) server.martini = m port := os.Getenv("PORT") if port == "" { port = "9091" } setupEditor(server) server.timelimit = config.GetInt("extension/timelimit", 30) server.extensions = config.GetStringList("extension/use", []string{ "javascript", "gohanscript", "go", }) schema.DefaultExtension = config.GetString("extension/default", "javascript") server.address = config.GetString("address", ":"+port) if config.GetBool("tls/enabled", false) { log.Info("TLS enabled") server.tls = &tlsConfig{ KeyFile: config.GetString("tls/key_file", "./etc/key.pem"), CertFile: config.GetString("tls/cert_file", "./etc/cert.pem"), } } etcdServers := config.GetStringList("etcd", nil) if etcdServers != nil { log.Info("etcd servers: %s", etcdServers) server.sync = etcd.NewSync(etcdServers) } server.connectDB() schemaFiles := config.GetStringList("schemas", nil) if schemaFiles == nil { log.Fatal("No schema specified in configuraion") } else { err = manager.LoadSchemasFromFiles(schemaFiles...) if err != nil { return nil, fmt.Errorf("invalid schema: %s", err) } } if !config.GetBool("database/no_init", false) { server.initDB() } if config.GetList("database/initial_data", nil) != nil { initialDataList := config.GetList("database/initial_data", nil) for _, initialData := range initialDataList { initialDataConfig := initialData.(map[string]interface{}) inType := initialDataConfig["type"].(string) inConnection := initialDataConfig["connection"].(string) log.Info("Importing data from %s ...", inConnection) inDB, err := db.ConnectDB(inType, inConnection, db.DefaultMaxOpenConn) if err != nil { log.Fatal(err) } db.CopyDBResources(inDB, server.db, false) } } if config.GetBool("keystone/use_keystone", false) { //TODO remove this if config.GetBool("keystone/fake", false) { server.keystoneIdentity = &middleware.FakeIdentity{} //TODO(marcin) requests to fake server also get authenticated // we need a separate routing Group log.Info("Debug Mode with Fake Keystone Server") } else { log.Info("Keystone backend server configured") server.keystoneIdentity, err = cloud.NewKeystoneIdentity( config.GetString("keystone/auth_url", "http://localhost:35357/v3"), config.GetString("keystone/user_name", "admin"), config.GetString("keystone/password", "password"), config.GetString("keystone/domain_name", "Default"), config.GetString("keystone/tenant_name", "admin"), config.GetString("keystone/version", ""), ) if err != nil { log.Fatal(err) } } m.MapTo(server.keystoneIdentity, (*middleware.IdentityService)(nil)) m.Use(middleware.Authentication()) //m.Use(Authorization()) } else { m.MapTo(&middleware.NoIdentityService{}, (*middleware.IdentityService)(nil)) m.Map(schema.NewAuthorization("admin", "admin", "admin_token", []string{"admin"}, nil)) } if err != nil { return nil, fmt.Errorf("invalid base dir: %s", err) } server.addOptionsRoute() cors := config.GetString("cors", "") if cors != "" { log.Info("Enabling CORS for %s", cors) if cors == "*" { log.Warning("cors for * have security issue") } server.martini.Use(func(rw http.ResponseWriter, r *http.Request) { rw.Header().Add("Access-Control-Allow-Origin", cors) rw.Header().Add("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type") rw.Header().Add("Access-Control-Expose-Headers", "X-Total-Count") rw.Header().Add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE") }) } documentRoot := config.GetString("document_root", "embed") if config.GetBool("webui_config/enabled", false) { m.Use(func(res http.ResponseWriter, req *http.Request, c martini.Context) { if req.URL.Path != "/webui/config.json" { c.Next() return } address := config.GetString("webui_config/address", server.address) if address[0] == ':' { address = "__HOST__" + address } baseURL := "http://" + address authURL := "http://" + address + "/v2.0" if config.GetBool("webui_config/tls", config.GetBool("tls/enabled", false)) { baseURL = "https://" + address authURL = "https://" + address + "/v2.0" } authURL = config.GetString("webui_config/auth_url", authURL) webUIConfig := map[string]interface{}{ "authUrl": authURL, "gohan": map[string]interface{}{ "schema": "/gohan/v0.1/schemas", "url": baseURL, }, } routes.ServeJson(res, webUIConfig) }) } if documentRoot == "embed" { m.Use(staticbin.Static("public", util.Asset, staticbin.Options{ SkipLogging: true, })) } else { log.Info("Static file serving from %s", documentRoot) documentRootABS, err := filepath.Abs(documentRoot) if err != nil { return nil, err } server.martini.Use(martini.Static(documentRootABS, martini.StaticOptions{ SkipLogging: true, })) } server.mapRoutes() maxWorkerCount := config.GetInt("workers", 100) server.queue = job.NewQueue(uint(maxWorkerCount)) return server, nil }