Пример #1
0
// Load returns a low-level "handler config" from the provided filename.
// If the config file doesn't contain a top-level JSON key of "handlerConfig"
// with boolean value true, the configuration is assumed to be a high-level
// "user config" file, and transformed into a low-level config.
func Load(filename string) (*Config, error) {
	obj, err := jsonconfig.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	conf := &Config{
		Obj:        obj,
		configPath: filename,
	}

	if lowLevel := obj.OptionalBool("handlerConfig", false); !lowLevel {
		conf, err = genLowLevelConfig(conf)
		if err != nil {
			return nil, fmt.Errorf(
				"Failed to transform user config file %q into internal handler configuration: %v",
				filename, err)
		}
		if v, _ := strconv.ParseBool(os.Getenv("CAMLI_DEBUG_CONFIG")); v {
			jsconf, _ := json.MarshalIndent(conf.Obj, "", "  ")
			log.Printf("From high-level config, generated low-level config: %s", jsconf)
		}
	}

	return conf, nil
}
Пример #2
0
// Reads google storage config and creates a Client.  Exits on error.
func doConfig(t *testing.T) (gsa *Client, bucket string) {
	if *gsConfigPath == "" {
		t.Skip("Skipping manual test. Set flag --gs_config_path to test Google Storage.")
	}

	cf, err := jsonconfig.ReadFile(*gsConfigPath)
	if err != nil {
		t.Fatalf("Failed to read config: %v", err)
	}

	var config jsonconfig.Obj
	config = cf.RequiredObject("gsconf")
	if err := cf.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	auth := config.RequiredObject("auth")
	bucket = config.RequiredString("bucket")
	if err := config.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	gsa = NewClient(MakeOauthTransport(auth.RequiredString("client_id"),
		auth.RequiredString("client_secret"),
		auth.RequiredString("refresh_token")))

	if err := auth.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}
	return
}
Пример #3
0
// Reads google storage config and creates a Client.  Exits on error.
func doConfig(t *testing.T) (gsa *Client, bucket string) {
	if *gsConfigPath == "" {
		t.Skip("Skipping manual test. Set flag --gs_config_path to test Google Storage.")
	}

	cf, err := jsonconfig.ReadFile(*gsConfigPath)
	if err != nil {
		t.Fatalf("Failed to read config: %v", err)
	}

	var config jsonconfig.Obj
	config = cf.RequiredObject("gsconf")
	if err := cf.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	auth := config.RequiredObject("auth")
	bucket = config.RequiredString("bucket")
	if err := config.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	gsa = NewClient(oauth2.NewClient(oauth2.NoContext, oauthutil.NewRefreshTokenSource(&oauth2.Config{
		Scopes:       []string{Scope},
		Endpoint:     google.Endpoint,
		ClientID:     auth.RequiredString("client_id"),
		ClientSecret: auth.RequiredString("client_secret"),
		RedirectURL:  oauthutil.TitleBarRedirectURL,
	}, auth.RequiredString("refresh_token"))))

	if err := auth.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}
	return
}
Пример #4
0
// Reads google storage config and creates a Client.  Exits on error.
func doConfig(t *testing.T) (gsa *Client, bucket string) {
	gsConfigPath := filepath.Join(osutil.CamliConfigDir(), "gstestconfig.json")

	if _, err := os.Stat(gsConfigPath); os.IsNotExist(err) {
		test.DependencyErrorOrSkip(t)
		t.Fatalf("Missing config file: %v", err)
	}
	cf, err := jsonconfig.ReadFile(gsConfigPath)
	if err != nil {
		t.Fatalf("Failed to read config: %v", err)
	}

	var config jsonconfig.Obj
	config = cf.RequiredObject("gsconf")
	if err := cf.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	auth := config.RequiredObject("auth")
	bucket = config.RequiredString("bucket")
	if err := config.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	gsa = NewClient(MakeOauthTransport(auth.RequiredString("client_id"),
		auth.RequiredString("client_secret"),
		auth.RequiredString("refresh_token")))

	if err := auth.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}
	return
}
Пример #5
0
func parseConfig() {
	if android.OnAndroid() {
		return
	}
	configPath := osutil.UserClientConfigPath()
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		errMsg := fmt.Sprintf("Client configuration file %v does not exist. See 'camput init' to generate it.", configPath)
		if keyId := serverKeyId(); keyId != "" {
			hint := fmt.Sprintf("\nThe key id %v was found in the server config %v, so you might want:\n'camput init -gpgkey %v'", keyId, osutil.UserServerConfigPath(), keyId)
			errMsg += hint
		}
		log.Fatal(errMsg)
	}

	conf, err := jsonconfig.ReadFile(configPath)
	if err != nil {
		log.Fatal(err.Error())
	}
	cfg := jsonconfig.Obj(conf)
	config = &clientConfig{
		auth:               cfg.OptionalString("auth", ""),
		server:             cfg.OptionalString("server", ""),
		identity:           cfg.OptionalString("identity", ""),
		identitySecretRing: cfg.OptionalString("identitySecretRing", osutil.IdentitySecretRing()),
		trustedCerts:       cfg.OptionalList("trustedCerts"),
		ignoredFiles:       cfg.OptionalList("ignoredFiles"),
	}
	if err := cfg.Validate(); err != nil {
		printConfigChangeHelp(cfg)
		log.Fatalf("Error in config file: %v", err)
	}
}
Пример #6
0
func handleSetupChange(rw http.ResponseWriter, req *http.Request) {
	hilevelConf, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	if !xsrftoken.Valid(req.FormValue("token"), serverKey, "user", "wizardSave") {
		http.Error(rw, "Form expired. Press back and reload form.", http.StatusBadRequest)
		log.Printf("invalid xsrf token=%q", req.FormValue("token"))
		return
	}

	hasChanged := false
	var el interface{}
	publish := jsonconfig.Obj{}
	for k, v := range req.Form {
		if _, ok := hilevelConf[k]; !ok {
			if k != "gallery" && k != "blog" {
				continue
			}
		}

		switch k {
		case "https", "shareHandler":
			b, err := strconv.ParseBool(v[0])
			if err != nil {
				httputil.ServeError(rw, req, fmt.Errorf("%v field expects a boolean value", k))
			}
			el = b
		default:
			el = v[0]
		}
		if reflect.DeepEqual(hilevelConf[k], el) {
			continue
		}
		hasChanged = true
		hilevelConf[k] = el
	}
	// "publish" wasn't checked yet
	if !reflect.DeepEqual(hilevelConf["publish"], publish) {
		hilevelConf["publish"] = publish
		hasChanged = true
	}

	if hasChanged {
		err = rewriteConfig(&hilevelConf, osutil.UserServerConfigPath())
		if err != nil {
			httputil.ServeError(rw, req, err)
			return
		}
		err = osutil.RestartProcess()
		if err != nil {
			log.Fatal("Failed to restart: " + err.Error())
			http.Error(rw, "Failed to restart process", 500)
			return
		}
	}
	sendWizard(rw, req, hasChanged)
}
Пример #7
0
func parseConfig() {
	configPath := ConfigFilePath()

	var err error
	if config, err = jsonconfig.ReadFile(configPath); err != nil {
		log.Fatal(err.Error())
		return
	}
}
Пример #8
0
func parseConfig() {
	configPath := ConfigFilePath()
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		parseConfigErr = os.ErrNotExist
		return
	}

	var err error
	if config, err = jsonconfig.ReadFile(configPath); err != nil {
		log.Fatal(err.Error())
		return
	}
}
Пример #9
0
func sendWizard(rw http.ResponseWriter, req *http.Request, hasChanged bool) {
	config, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	err = flattenPublish(config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	funcMap := template.FuncMap{
		"printWizard": printWizard,
		"showField": func(inputName string) bool {
			if _, ok := ignoredFields[inputName]; ok {
				return false
			}
			return true
		},
		"genXSRF": func() string {
			return xsrftoken.Generate(serverKey, "user", "wizardSave")
		},
	}

	body := `
	<form id="WizardForm" method="POST" enctype="multipart/form-data">
	<table>
	{{range $k,$v := .}}{{if showField $k}}<tr><td>{{printf "%v" $k}}</td><td><input type="text" size="30" name ="{{printf "%v" $k}}" value="{{printWizard $v}}" ></td></tr>{{end}}{{end}}
	</table>
	<input type="hidden" name="token" value="{{genXSRF}}">
	<input type="submit" form="WizardForm" value="Save"> (Will restart server.)</form>`

	if hasChanged {
		body += `<p> Configuration succesfully rewritten </p>`
	}

	tmpl, err := template.New("wizard").Funcs(funcMap).Parse(topWizard + body + bottomWizard)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	err = tmpl.Execute(rw, config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
}
Пример #10
0
func parseConfig() {
	configPath := osutil.UserClientConfigPath()
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		errMsg := fmt.Sprintf("Client configuration file %v does not exist. See 'camput init' to generate it.", configPath)
		if keyId := serverKeyId(); keyId != "" {
			hint := fmt.Sprintf("\nThe key id %v was found in the server config %v, so you might want:\n'camput init -gpgkey %v'", keyId, osutil.UserServerConfigPath(), keyId)
			errMsg += hint
		}
		log.Fatal(errMsg)
	}

	var err error
	if config, err = jsonconfig.ReadFile(configPath); err != nil {
		log.Fatal(err.Error())
		return
	}
}
Пример #11
0
func TestS3(t *testing.T) {
	cfgFile := os.Getenv("CAMLI_S3_TEST_CONFIG_JSON")
	if cfgFile == "" {
		t.Skip("Skipping manual test. To enable, set the environment variable CAMLI_S3_TEST_CONFIG_JSON to the path of a JSON configuration for the s3 storage type.")
	}
	conf, err := jsonconfig.ReadFile(cfgFile)
	if err != nil {
		t.Fatalf("Error reading s3 configuration file %s: %v", cfgFile, err)
	}
	storagetest.Test(t, func(t *testing.T) (sto blobserver.Storage, cleanup func()) {
		sto, err := newFromConfig(nil, conf)
		if err != nil {
			t.Fatalf("newFromConfig error: %v", err)
		}
		return sto, func() {}
	})
}
Пример #12
0
// Load returns a low-level "handler config" from the provided filename.
// If the config file doesn't contain a top-level JSON key of "handlerConfig"
// with boolean value true, the configuration is assumed to be a high-level
// "user config" file, and transformed into a low-level config.
func Load(filename string) (*Config, error) {
	obj, err := jsonconfig.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	conf := &Config{
		Obj:        obj,
		configPath: filename,
	}

	if lowLevel := obj.OptionalBool("handlerConfig", false); lowLevel {
		return conf, nil
	}

	if err := detectConfigChange(obj); err != nil {
		return nil, err
	}

	absConfigPath, err := filepath.Abs(filename)
	if err != nil {
		return nil, fmt.Errorf("Failed to expand absolute path for %s: %v", filename, err)
	}
	b, err := ioutil.ReadFile(absConfigPath)
	if err != nil {
		return nil, fmt.Errorf("Could not read %s: %v", absConfigPath, err)
	}
	var hiLevelConf serverconfig.Config
	if err := json.Unmarshal(b, &hiLevelConf); err != nil {
		return nil, fmt.Errorf("Could not unmarshal %s into a serverconfig.Config: %v", absConfigPath, err)
	}

	conf, err = genLowLevelConfig(&hiLevelConf)
	if err != nil {
		return nil, fmt.Errorf(
			"Failed to transform user config file %q into internal handler configuration: %v",
			filename, err)
	}
	if v, _ := strconv.ParseBool(os.Getenv("CAMLI_DEBUG_CONFIG")); v {
		jsconf, _ := json.MarshalIndent(conf.Obj, "", "  ")
		log.Printf("From high-level config, generated low-level config: %s", jsconf)
	}
	conf.configPath = absConfigPath

	return conf, nil
}
Пример #13
0
// serverKeyId returns the public gpg key id ("identity" field)
// from the user's server config , if any.
// It returns the empty string otherwise.
func serverKeyId() string {
	serverConfigFile := osutil.UserServerConfigPath()
	if _, err := os.Stat(serverConfigFile); err != nil {
		if os.IsNotExist(err) {
			return ""
		}
		log.Fatalf("Could not stat %v: %v", serverConfigFile, err)
	}
	obj, err := jsonconfig.ReadFile(serverConfigFile)
	if err != nil {
		return ""
	}
	keyId, ok := obj["identity"].(string)
	if !ok {
		return ""
	}
	return keyId
}
Пример #14
0
// Reads google storage config and creates a Client.  Exits on error.
func doConfig(t *testing.T) (gsa *Client, bucket string) {
	if _, err := os.Stat("gstestconfig.json"); os.IsNotExist(err) {
		testdep.CheckEnv(t)
		t.Fatalf("Missing config file: %v", err)
	}
	cf, err := jsonconfig.ReadFile("testconfig.json")
	if err != nil {
		t.Fatalf("Failed to read config: %v", err)
	}

	var config jsonconfig.Obj
	config = cf.RequiredObject("gsconf")
	if err := cf.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	auth := config.RequiredObject("auth")
	bucket = config.RequiredString("bucket")
	if err := config.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}

	gsa = NewClient(&oauth.Transport{
		&oauth.Config{
			ClientId:     auth.RequiredString("client_id"),
			ClientSecret: auth.RequiredString("client_secret"),
			Scope:        "https://www.googleapis.com/auth/devstorage.read_write",
			AuthURL:      "https://accounts.google.com/o/oauth2/auth",
			TokenURL:     "https://accounts.google.com/o/oauth2/token",
			RedirectURL:  "urn:ietf:wg:oauth:2.0:oob",
		},
		&oauth.Token{
			AccessToken:  "",
			RefreshToken: auth.RequiredString("refresh_token"),
		},
		nil,
	})

	if err := auth.Validate(); err != nil {
		t.Fatalf("Invalid config: %v", err)
	}
	return
}
Пример #15
0
func sendWizard(rw http.ResponseWriter, req *http.Request, hasChanged bool) {
	config, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServerError(rw, req, err)
		return
	}

	err = flattenPublish(config)
	if err != nil {
		httputil.ServerError(rw, req, err)
		return
	}

	funcMap := template.FuncMap{
		"printWizard":    printWizard,
		"inputIsGallery": func(inputName string) bool { return inputName == "gallery" },
	}

	body := `<form id="WizardForm" action="setup" method="post" enctype="multipart/form-data">`
	body += `{{range $k,$v := .}}{{printf "%v" $k}} <input type="text" size="30" name ="{{printf "%v" $k}}" value="{{printWizard $v}}" {{if inputIsGallery $k}}placeholder="/pics/,sha1-xxxx,pics.css"{{end}}><br />{{end}}`
	body += `<input type="submit" form="WizardForm" value="Save"></form>`

	if hasChanged {
		body += `<p> Configuration succesfully rewritten </p>`
	}

	tmpl, err := template.New("wizard").Funcs(funcMap).Parse(topWizard + body + bottomWizard)
	if err != nil {
		httputil.ServerError(rw, req, err)
		return
	}
	err = tmpl.Execute(rw, config)
	if err != nil {
		httputil.ServerError(rw, req, err)
		return
	}
}
Пример #16
0
func handleSetupChange(rw http.ResponseWriter, req *http.Request) {
	hilevelConf, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServerError(rw, req, err)
		return
	}

	hasChanged := false
	var el interface{}
	publish := jsonconfig.Obj{}
	for k, v := range req.Form {
		if _, ok := hilevelConf[k]; !ok {
			if k != "gallery" && k != "blog" {
				continue
			}
		}

		switch k {
		case "https":
			b, err := strconv.ParseBool(v[0])
			if err != nil {
				httputil.ServerError(rw, req, fmt.Errorf("https field expects a boolean value"))
			}
			el = b
		case "replicateTo":
			// TODO(mpl): figure out why it is always seen as different from the conf
			el = []interface{}{}
			if len(v[0]) > 0 {
				els := []string{}
				vals := strings.Split(v[0], ",")
				els = append(els, vals...)
				el = els
			}
		// TODO(mpl): "handler,rootPermanode[,style]" for each published entity for now.
		// we will need something more readable later probably
		case "gallery", "blog":
			if len(v[0]) > 0 {
				pub := strings.Split(v[0], ",")
				if len(pub) < 2 || len(pub) > 3 {
					// no need to fail loudly for now as we'll probably change this format
					continue
				}
				handler := jsonconfig.Obj{}
				handler["template"] = k
				handler["rootPermanode"] = pub[1]
				if len(pub) > 2 {
					handler["style"] = pub[2]
				}
				publish[pub[0]] = handler
			}
			continue
		default:
			el = v[0]
		}
		if reflect.DeepEqual(hilevelConf[k], el) {
			continue
		}
		hasChanged = true
		hilevelConf[k] = el
	}
	// "publish" wasn't checked yet
	if !reflect.DeepEqual(hilevelConf["publish"], publish) {
		hilevelConf["publish"] = publish
		hasChanged = true
	}

	if hasChanged {
		err = rewriteConfig(&hilevelConf, osutil.UserServerConfigPath())
		if err != nil {
			httputil.ServerError(rw, req, err)
			return
		}
	}
	sendWizard(rw, req, hasChanged)
	return
}
Пример #17
0
func parseConfig() {
	if android.OnAndroid() {
		panic("parseConfig should never have been called on Android")
	}
	configPath := osutil.UserClientConfigPath()
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		errMsg := fmt.Sprintf("Client configuration file %v does not exist. See 'camput init' to generate it.", configPath)
		if keyId := serverKeyId(); keyId != "" {
			hint := fmt.Sprintf("\nThe key id %v was found in the server config %v, so you might want:\n'camput init -gpgkey %v'", keyId, osutil.UserServerConfigPath(), keyId)
			errMsg += hint
		}
		log.Fatal(errMsg)
	}
	// TODO: instead of using jsonconfig, we could read the file, and unmarshall into the structs that we now have in pkg/types/clientconfig. But we'll have to add the old fields (before the name changes, and before the multi-servers change) to the structs as well for our gracefull conversion/error messages to work.
	conf, err := jsonconfig.ReadFile(configPath)
	if err != nil {
		log.Fatal(err.Error())
	}
	cfg := jsonconfig.Obj(conf)

	if singleServerAuth := cfg.OptionalString("auth", ""); singleServerAuth != "" {
		newConf, err := convertToMultiServers(cfg)
		if err != nil {
			log.Print(err)
		} else {
			cfg = newConf
		}
	}

	config = &clientconfig.Config{
		Identity:           cfg.OptionalString("identity", ""),
		IdentitySecretRing: cfg.OptionalString("identitySecretRing", osutil.IdentitySecretRing()),
		IgnoredFiles:       cfg.OptionalList("ignoredFiles"),
	}
	serversList := make(map[string]*clientconfig.Server)
	servers := cfg.OptionalObject("servers")
	for alias, vei := range servers {
		// An alias should never be confused with a host name,
		// so we forbid anything looking like one.
		if isURLOrHostPort(alias) {
			log.Fatalf("Server alias %q looks like a hostname; \".\" or \";\" are not allowed.", alias)
		}
		serverMap, ok := vei.(map[string]interface{})
		if !ok {
			log.Fatalf("entry %q in servers section is a %T, want an object", alias, vei)
		}
		serverConf := jsonconfig.Obj(serverMap)
		server := &clientconfig.Server{
			Server:       cleanServer(serverConf.OptionalString("server", "")),
			Auth:         serverConf.OptionalString("auth", ""),
			IsDefault:    serverConf.OptionalBool("default", false),
			TrustedCerts: serverConf.OptionalList("trustedCerts"),
		}
		if err := serverConf.Validate(); err != nil {
			log.Fatalf("Error in servers section of config file for server %q: %v", alias, err)
		}
		serversList[alias] = server
	}
	config.Servers = serversList
	if err := cfg.Validate(); err != nil {
		printConfigChangeHelp(cfg)
		log.Fatalf("Error in config file: %v", err)
	}
}