func (r *memStore) GetNonce() (string, error) { key, _ := util.GenUUID4() val, _ := util.GenUUID4() r.nonces[key] = val return fmt.Sprintf("%s-%s", key, val), nil }
// 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 }
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 }
// 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 }
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) } }