コード例 #1
0
ファイル: inmemory.go プロジェクト: jrconlin/FindMyDevice
func (r *memStore) GetNonce() (string, error) {
	key, _ := util.GenUUID4()
	val, _ := util.GenUUID4()

	r.nonces[key] = val
	return fmt.Sprintf("%s-%s", key, val), nil
}
コード例 #2
0
ファイル: pg.go プロジェクト: michielbdejong/FindMyDevice
// Generate a nonce for OAuth checks
func (self *pgStore) GetNonce() (string, error) {
	var statement string
	dbh := self.db

	key, _ := util.GenUUID4()
	val, _ := util.GenUUID4()
	statement = "insert into nonce (key, val, time) values ($1, $2, current_timestamp);"

	if _, err := dbh.Exec(statement, key, val); err != nil {
		return "", err
	}
	ret := key + "." + self.genSig(key, val)
	return ret, nil
}
コード例 #3
0
ファイル: inmemory.go プロジェクト: jrconlin/FindMyDevice
func (r *memStore) RegisterDevice(userid string, dev *Device) (devId string, err error) {

	if dev.ID == "" {
		dev.ID, _ = util.GenUUID4()
	}

	r.devices[dev.ID] = dev
	r.users[userid] = udmap{dev.ID, dev.Name}
	return dev.ID, nil
}
コード例 #4
0
ファイル: pg.go プロジェクト: michielbdejong/FindMyDevice
// Register a new device to a given userID.
func (self *pgStore) RegisterDevice(userid string, dev *Device) (devId string, err error) {
	var deviceId string
	dbh := self.db

	if dev.ID == "" {
		dev.ID, _ = util.GenUUID4()
	}
	// if the device belongs to the user already...
	err = dbh.QueryRow("select deviceid from userToDeviceMap where userId = $1 and deviceid=$2;", userid, dev.ID).Scan(&deviceId)
	if err == nil && deviceId == dev.ID {
		self.logger.Debug(self.logCat, "Updating db",
			util.Fields{"userId": userid, "deviceId": dev.ID})
		rows, err := dbh.Query("update deviceinfo set lockable=$1, loggedin=$2, lastExchange=$3, hawkSecret=$4, accepts=$5, pushUrl=$6 where deviceid=$7;",
			dev.HasPasscode,
			dev.LoggedIn,
			dbNow(),
			dev.Secret,
			dev.Accepts,
			dev.PushUrl,
			dev.ID)
		defer rows.Close()
		if err != nil {
			self.logger.Warn(self.logCat, "Device Info Update error",
				util.Fields{"error": err.Error()})
			return "", err
		} else {
			return dev.ID, nil
		}
	}
	// otherwise insert it.
	statement := "insert into deviceInfo (deviceId, lockable, loggedin, lastExchange, hawkSecret, accepts, pushUrl) values ($1, $2, $3, $4, $5, $6, $7);"
	rows, err := dbh.Query(statement,
		string(dev.ID),
		dev.HasPasscode,
		dev.LoggedIn,
		dbNow(),
		dev.Secret,
		dev.Accepts,
		dev.PushUrl)
	defer rows.Close()
	if err != nil {
		self.logger.Error(self.logCat, "Could not create device",
			util.Fields{"error": err.Error(),
				"device": fmt.Sprintf("%+v", dev)})
		return "", err
	}
	rows2, err := dbh.Query("insert into userToDeviceMap (userId, deviceId, name, date) values ($1, $2, $3, now());", userid, dev.ID, "")
	defer rows2.Close()
	if err != nil {
		switch {
		default:
			self.logger.Error(self.logCat,
				"Could not map device to user",
				util.Fields{
					"uid":      userid,
					"deviceId": dev.ID,
					"name":     dev.Name,
					"error":    err.Error()})
			return "", err
		}
	}
	return dev.ID, nil
}
コード例 #5
0
ファイル: main.go プロジェクト: michielbdejong/FindMyDevice
func main() {
	if _, err := flags.ParseArgs(&opts, os.Args); err != nil {
		log.Fatalf(err.Error())
		return
	}

	// Configuration
	// TODO: switch to regular go flag package
	// defaults don't appear to work.
	if opts.ConfigFile == "" {
		opts.ConfigFile = "config.ini"
	}

	config, err := util.ReadMzConfig(opts.ConfigFile)
	if err != nil {
		log.Fatalf("Could not read config file %s: %s", opts.ConfigFile, err.Error())
		return
	}

	fullVers := fmt.Sprintf("%s-%s", config.Get("VERSION", VERSION),
		getCodeVersion())
	config.Override("VERSION", fullVers)
	config.Override("SERVER", SERVER)
	config.Override("ddl.create", opts.Ddlcreate)
	config.Override("ddl.downgrade", opts.Ddldowngrade)
	if opts.LogFile != "" {
		config.Override("logger.output", opts.LogFile)
	}
	if opts.Ddlupgrade {
		config.SetDefaultFlag("ddl.upgrade", true)
	}
	if opts.Ddllog {
		config.SetDefaultFlag("ddl.log", true)
	}
	sock_secret, _ := util.GenUUID4()
	config.SetDefault("ws.socket_secret", sock_secret)

	// Rest Config
	errChan := make(chan error)
	host := config.Get("host", "localhost")
	port := config.Get("port", "8080")

	if config.GetFlag("aws.get_hostname") {
		if hostname, err := util.GetAWSPublicHostname(); err == nil {
			config.SetDefault("ws_hostname", hostname)
		}
		if port != "80" {
			config.SetDefault("ws_hostname", config.Get("ws_hostname", "")+":"+port)
		}
	}

	// Partner cert pool contains the various self-signed certs that
	// partners may require to access their servers (for Proprietary
	// wake mechanisms like UDP)
	// This would be where you collect the certs and store them into
	// the config map as something like:
	// config["partnerCertPool"] = self.loadCerts()

	if opts.Profile != "" {
		log.Printf("Creating profile %s...\n", opts.Profile)
		f, err := os.Create(opts.Profile)
		if err != nil {
			log.Fatal(fmt.Sprintf("Profile creation failed:\n%s\n",
				err.Error()))
			return
		}
		defer func() {
			log.Printf("Writing app profile...\n")
			pprof.StopCPUProfile()
		}()
		pprof.StartCPUProfile(f)
	}
	if opts.MemProfile != "" {
		defer func() {
			profFile, err := os.Create(opts.MemProfile)
			if err != nil {
				log.Fatal(fmt.Sprintf("Memory Profile creation failed:\n%s\n", err.Error()))
				return
			}
			log.Printf("Writing memory profile...\n")
			pprof.WriteHeapProfile(profFile)
			profFile.Close()
		}()
	}

	runtime.GOMAXPROCS(runtime.NumCPU())
	logger := util.NewLogger(config)
	metrics := util.NewMetrics(config.Get(
		"metrics.prefix",
		"wmf"), logger, config)
	if err != nil {
		logger.Error("main", "Unable to connect to database. Have you configured it yet?", nil)
		return
	}
	if hawkCount := config.Get("hawk.nonce_cache", "1000"); hawkCount != "1000" {
		count, err := strconv.ParseInt(hawkCount, 10, 32)
		if err != nil {
			log.Printf("Could not read hawk.nonce_cache, defaulting to 1000")
		} else {
			wmf.InitHawkNonces(count)
		}
	}
	handlers := wmf.NewHandler(config, logger, metrics)
	if handlers == nil {
		log.Fatalf("Could not start server. Please check config.ini")
	}

	// Signal handler
	sigChan := make(chan os.Signal)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGHUP, syscall.SIGUSR1)

	var RESTMux = http.DefaultServeMux
	var WSMux = http.DefaultServeMux
	var verRoot = strings.SplitN(VERSION, ".", 2)[0]

	// REST calls

	RESTMux.HandleFunc(fmt.Sprintf("/%s/register/", verRoot),
		handlers.Register)
	RESTMux.HandleFunc(fmt.Sprintf("/%s/cmd/", verRoot),
		handlers.Cmd)
	// Web UI calls
	RESTMux.HandleFunc(fmt.Sprintf("/%s/queue/", verRoot),
		handlers.RestQueue)
	RESTMux.HandleFunc(fmt.Sprintf("/%s/state/", verRoot),
		handlers.State)
	RESTMux.HandleFunc(fmt.Sprintf("/%s/l10n/client.json", verRoot),
		handlers.Language)
	// Static files (served by nginx in production)
	if config.GetFlag("use_insecure_static") {
		RESTMux.HandleFunc("/bower_components/",
			handlers.Static)
		RESTMux.HandleFunc("/images/",
			handlers.Static)
		RESTMux.HandleFunc("/scripts/",
			handlers.Static)
		RESTMux.HandleFunc("/styles/",
			handlers.Static)
	}
	// Metrics
	RESTMux.HandleFunc("/metrics/",
		handlers.Metrics)
	// Operations call
	RESTMux.HandleFunc("/status/",
		handlers.Status)
	//Signin
	// set state nonce & check if valid at signin
	RESTMux.HandleFunc("/signin/",
		handlers.Signin)
	//Signout
	RESTMux.HandleFunc("/signout/",
		handlers.Signout)
	// Config option because there are other teams involved.
	auth := config.Get("fxa.redir_uri", "/oauth/")
	RESTMux.HandleFunc(auth, handlers.OAuthCallback)

	WSMux.Handle(fmt.Sprintf("/%s/ws/", verRoot),
		websocket.Handler(handlers.WSSocketHandler))
	// Handle root calls as webUI
	// Get a list of registered devices for the currently logged in user
	RESTMux.HandleFunc(fmt.Sprintf("/%s/devices/", verRoot),
		handlers.UserDevices)
	// Get an object describing the data for a user's device
	// e.g. http://host/0/data/0123deviceid
	RESTMux.HandleFunc(fmt.Sprintf("/%s/data/", verRoot),
		handlers.InitDataJson)
	RESTMux.HandleFunc(fmt.Sprintf("/%s/validate/", verRoot),
		handlers.Validate)
	RESTMux.HandleFunc("/",
		handlers.Index)

	logger.Info("main", "startup...",
		util.Fields{"host": host, "port": port, "version": fullVers})

	go func() {
		errChan <- http.ListenAndServe(host+":"+port, nil)
	}()

	select {
	case err := <-errChan:
		if err != nil {
			log.Fatalf("ListenAndServe: " + err.Error())
		}
	case <-sigChan:
		logger.Info("main", "Shutting down...", nil)
	}
}