func login_check(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf-8") var login string if r.Method == "GET" { cookie, err := r.Cookie("sessionToken") if err == nil { cookie_uuid, parse_error := gocql.ParseUUID(strings.TrimPrefix(cookie.String(), "sessionToken=")) if parse_error != nil { w.WriteHeader(403) fmt.Fprintf(w, "{\"error\":\"unauthorized\"}\n") return } if request_err := session.Query("select login from cookies where cookie = ?", cookie_uuid).Consistency(gocql.One).Scan(&login); request_err != nil { if request_err == gocql.ErrNotFound { w.WriteHeader(403) fmt.Fprintf(w, "{\"error\":\"unauthorized\"}\n") return } else { w.WriteHeader(500) return } } fmt.Fprintf(w, "{\"status\":\"You logged in!\"}\n") } else { w.WriteHeader(403) fmt.Fprintf(w, "{\"error\":\"unauthorized\"}\n") return } } else { w.WriteHeader(405) fmt.Fprintf(w, "{\"error\":\"Allowed methods: GET\"}\n") } }
func (asset *Asset) Find(session *gocql.Session, assetId string) (*Asset, error) { var id gocql.UUID var name string var path string var contentType string var createdAt time.Time var binary []byte // Check if the assetId is an valid UUID idCheck, err := gocql.ParseUUID(assetId) if err != nil { return nil, err } if idCheck.Timestamp() == 0 { return nil, errors.New("Invalid UUID") } if err := session.Query(`SELECT id, name, path, contenttype, createdat, binary FROM assets WHERE id = ? LIMIT 1`, assetId).Consistency(gocql.One).Scan(&id, &name, &path, &contentType, &createdAt, &binary); err != nil { return nil, err } return &Asset{id, name, strings.Split(path, ","), contentType, createdAt, binary}, nil }
func (c *Command) Execute(message []byte) { if !c.connection.GetServerAuthState() { return } var commandDetector CommandDetector json.Unmarshal(message, &commandDetector) var isLock bool = false userUUID, err := gocql.ParseUUID(commandDetector.UserUUID) if err != nil { } else { user, err := model_user.Get(userUUID) logger.String(fmt.Sprintf("commandDetector.UserUUID %+v, user %+v", commandDetector.UserUUID, user)) if err == nil && user != nil && user.IsLock { isLock = true } } b, _ := json.Marshal(map[string]interface{}{ "command": "answer", "command_id": commandDetector.CommandId, "is_lock": isLock, }) c.connection.Send(string(b)) }
func (conn *CassConnection) LookupDeviceByStringID( id string) (datalayer.Device, error) { deviceId, err := gocql.ParseUUID(id) if err != nil { canolog.Error(err) return nil, err } return conn.LookupDevice(deviceId) }
func mockExercise() *sitrep.ExerciseByIdentifier { uuid, err := gocql.ParseUUID("582412e9-6e2b-493f-b5ed-889f42584861") if err != nil { panic(err) } return &sitrep.ExerciseByIdentifier{ Id: uuid, ExerciseDescription: "Beta Exercise Description", ExerciseName: "Beta Exercise", HasActivation: true, IsActive: true, ActiveUntil: time.Now().Add(time.Hour * 72), } }
func LoadOrCreateSession(uuid string, remoteAddr string, userAgent string) *Session { s := New() var err error s.UUID, err = gocql.ParseUUID(uuid) if err == nil { s.Load() } if !s.Exists || (len(remoteAddr) > 0 && remoteAddr != s.RemoteAddr) || userAgent != s.UserAgent { logger.String(fmt.Sprintf("remoteAddr %s %s, userAgent %s %s", remoteAddr, s.RemoteAddr, userAgent, s.UserAgent)) s.Create(remoteAddr, userAgent) } return s }
func (d *D) loadService(servicename string) (*S, error) { if servicename == "" { return nil, errors.New("No service name has been specified") } cluster := gocql.NewCluster(d.cluster) cluster.Keyspace = d.keyspace session, err := cluster.CreateSession() if err != nil { return nil, err } defer session.Close() var ii, an, av string s := S{name: servicename} iMap := make(map[string]*I) iter := session.Query("SELECT instance_id, attribute_name, attribute_value FROM attributes WHERE service_name = ?", servicename).Iter() for iter.Scan(&ii, &an, &av) { var i *I var ok bool if i, ok = iMap[ii]; !ok { var id gocql.UUID var err error if id, err = gocql.ParseUUID(ii); err != nil { return nil, errors.New("could not parse instance id " + ii) } i = &I{id: id, attributes: make(map[string]string)} iMap[ii] = i } i.attributes[an] = av } if err := iter.Close(); err != nil { return nil, err } s.instances = iMap return &s, nil }
func exercisify(inner func(http.ResponseWriter, *http.Request, *sitrep.UsersByEmail, *sitrep.ExerciseByIdentifier), h *Handler, requireAuthentication bool) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { exerciseIDRaw, err := parseExerciseID(r) if err != nil { makeForbidden(w, err) return } exerciseID, err := gocql.ParseUUID(exerciseIDRaw) if err != nil { makeForbidden(w, err) return } exercise, err := models.FindExerciseByID(h.Cassandra, exerciseID) if err != nil { makeForbidden(w, err) return } if !requireAuthentication { inner(w, r, nil, exercise) return } counter := metrics.GetOrRegisterCounter(statAuthFail, h.statMap) accessToken, err := parseCredentials(r) if err != nil { counter.Inc(1) makeForbidden(w, err) return } user, err := models.VerifyUserRequest(h.Cassandra, accessToken) if err != nil { counter.Inc(1) makeForbidden(w, err) return } inner(w, r, user, exercise) }) }
func exercisifyOnly(inner func(http.ResponseWriter, *http.Request, *sitrep.ExerciseByIdentifier), h *Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { exerciseIDRaw, err := parseExerciseID(r) if err != nil { makeForbidden(w, err) return } exerciseID, err := gocql.ParseUUID(exerciseIDRaw) if err != nil { makeForbidden(w, err) return } exercise, err := models.FindExerciseByID(h.Cassandra, exerciseID) if err != nil { makeForbidden(w, err) return } inner(w, r, exercise) }) }
func logout(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf-8") cookie, err := r.Cookie("sessionToken") if r.Method == "POST" { if err == nil { cookie_uuid, parse_error := gocql.ParseUUID(strings.TrimPrefix(cookie.String(), "sessionToken=")) if parse_error != nil { w.WriteHeader(400) fmt.Fprintf(w, "{\"error\":\"bad cookie\"}\n") return } if request_err := session.Query("delete from cookies where cookie = ?", cookie_uuid).Exec(); request_err != nil { fmt.Println(request_err) w.WriteHeader(500) return } } fmt.Fprintf(w, "{\"error\":\"\"}\n") } else { w.WriteHeader(405) fmt.Fprintf(w, "{\"error\":\"Allowed methods: GET\"}\n") } }
// Lookup device by ID string in the URL. The ID string may be a UUID or // "self". Verifies that the requester has permission to access to the // requested device, returning an error if unathorized. func getDeviceByIdString(info *RestRequestInfo) (datalayer.Device, RestError) { deviceIdString := info.URLVars["id"] if deviceIdString == "self" { if info.Device == nil { // TODO: should be unauthorized return nil, BadInputError("Expected device credentials with /api/device/self").Log() } return info.Device, nil } else { uuid, err := gocql.ParseUUID(deviceIdString) if err != nil { return nil, URLNotFoundError() } // TODO: support anonymous device creation if info.Account != nil { device, err := info.Account.Device(uuid) if err != nil { // TODO: What errors to return here? return nil, InternalServerError("Device lookup failed").Log() } return device, nil } else if info.Device != nil { if deviceIdString != string(info.Device.IDString()) { // TODO: what error to return? // TODO: This should be allowed if the device has adequate // permissions. return nil, InternalServerError("Device mismatch").Log() } return info.Device, nil } else { return nil, NotLoggedInError() } } }
func main() { log.SetFlags(log.Llongfile) expvar.Publish("Goroutines", expvar.Func(goroutines)) runtime.GOMAXPROCS(6) var err *errors.Error config, err = readConfig() if err != nil { // logger.Error(fmt.Sprintf("readConfig - %v", err)) log.Fatal(err) // log.Fatal("ListenAndServe: ", err) os.Exit(0) } logger.Init(config.Logger.Path) if config.Daemonize { flag.Parse() daemon.AddCommand(daemon.StringFlag(signal, "quit"), syscall.SIGQUIT, termHandler) daemon.AddCommand(daemon.StringFlag(signal, "stop"), syscall.SIGTERM, termHandler) daemon.AddCommand(daemon.StringFlag(signal, "reload"), syscall.SIGHUP, reloadHandler) cntxt := &daemon.Context{ PidFileName: config.PidFilepath, PidFilePerm: 0644, LogFileName: config.Logger.Path + "/stdout.log", LogFilePerm: 0640, WorkDir: "./", Umask: 027, Args: []string{"[spacecraft-online]"}, } if len(daemon.ActiveFlags()) > 0 { d, err := cntxt.Search() if err != nil { log.Fatalln("Unable send signal to the daemon:", err) } daemon.SendCommands(d) return } d, err := cntxt.Reborn() if err != nil { log.Fatalln(err) } if d != nil { return } defer cntxt.Release() } logger.String(fmt.Sprintf("started")) cluster := gocql.NewCluster(config.Cassandra.IP) cluster.Keyspace = "sc_2" cluster.Consistency = 1 session, berr := cluster.CreateSession() model_server.Init(session) ip, t := localIP() if t != nil { logger.Error(errors.New(t)) os.Exit(0) } server := model_server.New(ip, config.Http.Port) model.Init(server.UUID, session) server.StartUpdater() star.SetLocalServer(server) bdispatcher := buildings.NewDispatcher(config.Buildings.PoolSize) model2.InstallModels(session, server.UUID, model2_auth_session.InstallInfo, model2_user.InstallInfo, model2_live_planet.InstallInfo, model2_building.InstallInfo, model2_player.InstallInfo) var connectionFactory = factory.New() // clients commands connectionFactory.InstallCommand("auth", cmd_auth.Generator) connectionFactory.InstallCommand("logout", cmd_logout.Generator) connectionFactory.InstallCommand("set_section", cmd_set_section.Generator) connectionFactory.InstallCommand("start", cmd_start.Generator) connectionFactory.InstallCommand("get_planet", cmd_get_planet.Generator) connectionFactory.InstallCommand("get_planet_buildings_for_construct", cmd_get_planet_buildings_for_construct.Generator) connectionFactory.InstallCommand("build", cmd_build.Generator) // star commands connectionFactory.InstallCommand("get_session_lock_state", cmd_session_lock_state.Generator) connectionFactory.InstallCommand("get_user_lock_state", cmd_user_lock_state.Generator) connectionFactory.InstallCommand("star_user_logout", cmd_user_logout.Generator) commandContext := &command.Context{Factory: connectionFactory, CQLSession: session, Config: config, ServerUUID: server.UUID, BDispatcher: bdispatcher} star.SetCommands(connectionFactory.GetCommands(), commandContext) http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { logger.String("/ws") if r.Method != "GET" { http.Error(w, "Method not allowed", 405) return } ws, err := connection.Upgrader.Upgrade(w, r, nil) if err != nil { logger.Error(errors.New(err)) return } ra := r.RemoteAddr[:strings.Index(r.RemoteAddr, ":")] c := connectionFactory.CreateConnection(ws, commandContext, ra, r.Header["User-Agent"][0]) // logger.String(ra) // logger.String(r.Header["User-Agent"][0]) logger.String(fmt.Sprintf("accept connection %v", c.Id)) // go c.Writing() c.Reading() c.Close() logger.String(fmt.Sprintf("close connection %v", c.Id)) }) http.HandleFunc("/debug", func(w http.ResponseWriter, r *http.Request) { b, err := json.Marshal(connectionFactory.MakeDebugInfo()) if err != nil { logger.Error(errors.New(err)) } io.WriteString(w, string(b)) }) http.HandleFunc("/api/auth/success", func(w http.ResponseWriter, r *http.Request) { logger.String("/api/auth/success") /* ra := r.RemoteAddr[:strings.Index(r.RemoteAddr, ":")] logger.String("remoteAdder " + ra) logger.String(fmt.Sprintf("%+v", r.Header)) */ client := &http.Client{} req, err := http.NewRequest("GET", "http://auth.spacecraft-online.org/api/check_token?token="+r.URL.Query().Get("token"), nil) if err != nil { logger.Error(errors.New(err)) return } resp, err := client.Do(req) if err != nil { logger.Error(errors.New(err)) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { logger.Error(errors.New(err)) return } if string(body) != "{\"status\":\"ok\",\"result\":true}" { logger.String(string(body)) http.Redirect(w, r, "/", http.StatusMovedPermanently) // logger.Error(errors.New(err)) return } // logger.String(string(body)) sessionUUID, err := gocql.ParseUUID(r.URL.Query().Get("session_uuid")) if err != nil { http.Redirect(w, r, "/", http.StatusMovedPermanently) return } session, err := model2_auth_session.Get(sessionUUID) if err != nil || session == nil { http.Redirect(w, r, "/", http.StatusMovedPermanently) return } // session := model_auth_session.LoadOrCreateSession(session_uuid, "", r.Header["User-Agent"][0]) method := r.URL.Query().Get("method") unique := r.URL.Query().Get("unique") user, _ := model2_user.GetByMethod(method, unique) if session.IsAuth { // check for another user and relogin if user.Exists && user.UUID.String() != session.UserUUID.String() { user.AddMethod(method, unique) } else { } } else { // loging if !user.Exists { user, _ = model2_user.Create() user.Update(model2.Fields{ "Name": r.URL.Query().Get("username"), }) user.AddMethod(method, unique) } } session.Update(model2.Fields{ "IsAuth": true, "UserUUID": user.UUID, "AuthMethod": method, }) http.Redirect(w, r, "/", http.StatusMovedPermanently) }) listen := fmt.Sprintf(":%v", config.Http.Port) logger.String(fmt.Sprintf("listen http %v", listen)) berr = http.ListenAndServe(listen, nil) if berr != nil { // logger.Error(fmt.Sprintf("ListenAndServe - %v", err)) logger.Error(errors.New(berr)) // log.Fatal("ListenAndServe: ", err) os.Exit(0) } go worker() derr := daemon.ServeSignals() if derr != nil { log.Println("Error:", derr) } // log.Println("daemon terminated") logger.String(fmt.Sprintf("daemon terminated")) }
func (c *Command) Execute(message []byte) { var commandDetector CommandDetector json.Unmarshal(message, &commandDetector) // inner connection auth if commandDetector.ServerUUID != nil { ServerUUID, _ := gocql.ParseUUID(*commandDetector.ServerUUID) // todo: check err server := model_server.Get(ServerUUID) answer := "error" if server.Exists && c.connection.GetRemoteAddr() == server.IP { c.connection.SetServerAuthState() answer = "ok" } c.connection.Send(`{"command":"` + answer + `"}`) return } // --------------- var session *model2_auth_session.Fields sessionUUID, err := gocql.ParseUUID(commandDetector.SessionUUID) if err == nil { session, err = model2_auth_session.Load(sessionUUID) if session != nil { if session.Exists { if session.RemoteAddr != c.connection.GetRemoteAddr() || session.UserAgent != c.connection.GetUserAgent() { session = nil } } else { session = nil } } } if err != nil || session == nil { session, err = model2_auth_session.Create() session.Update(model2.Fields{ "RemoteAddr": c.connection.GetRemoteAddr(), "UserAgent": c.connection.GetUserAgent(), }) } if session.IsLock { b, err := star.Send(session.LockServerUUID, model.Fields{ "command": "get_session_lock_state", "session_uuid": session.UUID, }) var commandCheckSessionDetector CommandCheckSessionDetector if err == nil { json.Unmarshal(b, &commandCheckSessionDetector) } if err != nil || commandCheckSessionDetector.IsLock { // session.Create(c.connection.GetRemoteAddr(), c.connection.GetUserAgent()) session, err = model2_auth_session.Create() session.Update(model2.Fields{ "RemoteAddr": c.connection.GetRemoteAddr(), "UserAgent": c.connection.GetUserAgent(), }) } logger.String(string(b)) } // session.Lock() c.connection.SetSession(session) sendCommandAuth := SendCommandAuth{ Command: "auth", SessionUUID: session.UUID.String(), AuthMethods: c.ctx.Config.Auth.Methods, IsAuth: session.IsAuth, PlayerExists: false, } if session.IsAuth { /* user := model2_user.New() user.UUID = session.UserUUID user.Load() */ user, _ := model2_user.Load(session.UserUUID) logger.String(fmt.Sprintf("user: %+v", user)) // check for user lock if user.IsLock { b, err := star.Send(user.LockServerUUID, model.Fields{ "command": "get_user_lock_state", "user_uuid": user.UUID.String(), }) if err != nil { } else { type CommandCheckUserDetector struct { IsLock bool `json:"is_lock"` } var commandCheckUserDetector CommandCheckUserDetector json.Unmarshal(b, &commandCheckUserDetector) if commandCheckUserDetector.IsLock { _, _ = star.Send(user.LockServerUUID, model.Fields{ "command": "star_user_logout", "user_uuid": user.UUID, "session_uuid": session.UUID.String(), }) user.Load() } } } // user.Lock() if user.PlayerUUID != nil { sendCommandAuth.PlayerExists = true } sendCommandAuth.User = SendCommandAuthUser{ Name: user.Name, SectionName: user.SectionName, } } b, err := json.Marshal(sendCommandAuth) if err != nil { logger.Error(errors.New(err)) return } c.connection.Send(string(b)) }
// Process communication payload from device (via websocket. or REST) // { // "device_id" : "9dfe2a00-efe2-45f9-a84c-8afc69caf4e7", // "sddl" : { // "optional inbound bool onoff" : {} // }, // "vars" : { // "temperature" : 38.0f; // "gps" : { // "latitude" : 38.0f; // "longitude" : 38.0f; // } // } // } // } // // <conn> is an optional datalayer connection. If provided, it is used. // Otherwise, a datalayer connection is opened by this routine. // // <device> is the device that sent the communication. If nil, then either // <deviceId> or, as a last resort, the payload's "device_id" will be used. // // <deviceId> is a string device ID of the device that sent the communication. // This is ignored if <device> is not nil. If nil, then the payload's // "device_id" will be used. // // <secretKey> is the device's secret key. A secret key is required if // <device> is nil. Either the value of <secretKey> or, as a last resort, the // payload's "secret_key" field will be used. // // <payload> is a string containing the JSON payload. func ProcessDeviceComm( cfg config.Config, conn datalayer.Connection, device datalayer.Device, deviceIdString string, secretKey string, payload string) ServiceResponse { var err error var out ServiceResponse var ok bool canolog.Info("ProcessDeviceComm STARTED") // If conn is nil, open a datalayer connection. if conn == nil { dl := cassandra_datalayer.NewDatalayer(cfg) conn, err = dl.Connect("canopy") if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Could not connect to database: %s", err), Response: `{"result" : "error", "error_type" : "could_not_connect_to_database"}`, Device: nil, } } defer conn.Close() } // Parse JSON payload var payloadObj map[string]interface{} err = json.Unmarshal([]byte(payload), &payloadObj) if err != nil { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Error JSON decoding payload: %s", err), Response: `{"result" : "error", "error_type" : "decoding_paylaod"}`, Device: nil, } } // Device can be provided to this routine in one of three ways: // 1) <device> parameter // 2) <deviceId> parameter // 3) "device_id" field in payload if device == nil && deviceIdString != "" { // Parse UUID uuid, err := gocql.ParseUUID(deviceIdString) if err != nil { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Invalid UUID %s: %s", deviceIdString, err), Response: `{"result" : "error", "error_type" : "device_uuid_required"}`, Device: nil, } } // Get secret key from payload if necessary if secretKey == "" { secretKey, ok = payloadObj["secret_key"].(string) if !ok { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("\"secret_key\" field must be string"), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } } // lookup device device, err = conn.LookupDeviceVerifySecretKey(uuid, secretKey) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error looking up or verifying device: %s", err), Response: `{"result" : "error", "error_type" : "database_error"}`, Device: nil, } } } // Is "device_id" provided in payload? _, ok = payloadObj["device_id"] if ok { deviceIdStringFromPayload, ok := payloadObj["device_id"].(string) if !ok { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("\"device_id\" field must be string"), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } // Parse UUID uuid, err := gocql.ParseUUID(deviceIdStringFromPayload) if err != nil { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Invalid UUID %s: %s", deviceIdStringFromPayload, err), Response: `{"result" : "error", "error_type" : "device_uuid_required"}`, Device: nil, } } // Is <device> already set? // If not: set it. // If so: ensure consistency if device == nil { // Get secret key from payload if necessary if secretKey == "" { secretKey, ok = payloadObj["secret_key"].(string) if !ok { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("\"secret_key\" field must be string"), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } } // Lookup device device, err = conn.LookupDeviceVerifySecretKey(uuid, secretKey) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error looking up or verifying device: %s", err), Response: `{"result" : "error", "error_type" : "database_error"}`, Device: nil, } } } else { if device.ID().String() != deviceIdStringFromPayload { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Inconsistent device ID: %s %s", device.ID().String(), deviceIdStringFromPayload), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } } } // If device wasn't provided at all, throw error. if device == nil { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Device ID expected"), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } out.Device = device device.UpdateLastActivityTime(nil) // If "sddl" is present, create new / reconfigure Cloud Variables. _, ok = payloadObj["sddl"] if ok { updateMap, ok := payloadObj["sddl"].(map[string]interface{}) if !ok { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Expected object for \"sdd\" field"), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } err = device.ExtendSDDL(updateMap) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error updating device's SDDL: %s", err), Response: `{"result" : "error", "error_type" : "database_error"}`, Device: nil, } } } // If "vars" is present, update value of all Cloud Variables (creating new // Cloud Variables as necessary) doc := device.SDDLDocument() _, ok = payloadObj["vars"] canolog.Info("vars present:", ok) if ok { varsMap, ok := payloadObj["vars"].(map[string]interface{}) if !ok { return ServiceResponse{ HttpCode: http.StatusBadRequest, Err: fmt.Errorf("Expected object for \"vars\" field"), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } canolog.Info("varsMap: ", varsMap) for varName, value := range varsMap { varDef, err := doc.LookupVarDef(varName) // TODO: an error doesn't necessarily mean prop should be created? canolog.Info("Looking up property ", varName) if varDef == nil { // Property doesn't exist. Add it. canolog.Info("Not found. Add property ", varName) // TODO: What datatype? // TODO: What other parameters? varDef, err = doc.AddVarDef(varName, sddl.DATATYPE_FLOAT32) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error creating cloud variable %s: %s", varName, err), Response: `{"result" : "error", "error_type" : "database_error"}`, Device: nil, } } // save modified SDDL // TODO: Save at the end? canolog.Info("SetSDDLDocument ", doc) err = device.SetSDDLDocument(doc) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error updating SDDL: %s", err), Response: `{"result" : "error", "error_type" : "database_error"}`, Device: nil, } } } // Store property value. // Convert value datatype varVal, err := cloudvar.JsonToCloudVarValue(varDef, value) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error converting JSON to propertyValue: %s", err), Response: `{"result" : "error", "error_type" : "bad_payload"}`, Device: nil, } } canolog.Info("InsertStample") err = device.InsertSample(varDef, time.Now(), varVal) if err != nil { return ServiceResponse{ HttpCode: http.StatusInternalServerError, Err: fmt.Errorf("Error inserting sample %s: %s", varName, err), Response: `{"result" : "error", "error_type" : "database_error"}`, Device: nil, } } } } return ServiceResponse{ HttpCode: http.StatusOK, Err: nil, Response: `{"result" : "ok"}`, Device: device, } }
func main() { cfg := config.NewDefaultConfig("", "", "") err := cfg.LoadConfig() if err != nil { fmt.Printf("Error loading config") } err = canolog.Init(".canopy-ops.log") if err != nil { fmt.Println(err) return } flag.Parse() cmd := canopy_ops.FindCommand(cmds, flag.Arg(0)) info := canopy_ops.CommandInfo{ CmdList: cmds, Cfg: cfg, Args: flag.Args(), } if cmd != nil { cmd.Perform(info) } else if flag.Arg(0) == "create-account" { dl := cassandra_datalayer.NewDatalayer(cfg) conn, _ := dl.Connect("canopy") conn.CreateAccount(flag.Arg(1), flag.Arg(2), flag.Arg(3)) } else if flag.Arg(0) == "delete-account" { dl := cassandra_datalayer.NewDatalayer(cfg) conn, _ := dl.Connect("canopy") conn.DeleteAccount(flag.Arg(1)) } else if flag.Arg(0) == "create-device" { dl := cassandra_datalayer.NewDatalayer(cfg) conn, _ := dl.Connect("canopy") account, err := conn.LookupAccount(flag.Arg(1)) if err != nil { fmt.Println("Unable to lookup account ", flag.Arg(1), ":", err) return } device, err := conn.CreateDevice(flag.Arg(2), nil, "", datalayer.NoAccess) if err != nil { fmt.Println("Unable to create device: ", err) return } err = device.SetAccountAccess(account, datalayer.ReadWriteAccess, datalayer.ShareRevokeAllowed) if err != nil { fmt.Println("Unable to grant account access to device: ", err) return } } else if flag.Arg(0) == "list-devices" { dl := cassandra_datalayer.NewDatalayer(cfg) conn, _ := dl.Connect("canopy") account, err := conn.LookupAccount(flag.Arg(1)) if err != nil { fmt.Println("Unable to lookup account ", flag.Arg(1), ":", err) return } devices, err := account.Devices().DeviceList(0, -1) if err != nil { fmt.Println("Error reading devices: ", err) return } for _, device := range devices { fmt.Printf("%s %s\n", device.ID(), device.Name()) } } else if flag.Arg(0) == "gen-fake-sensor-data" { dl := cassandra_datalayer.NewDatalayer(cfg) conn, _ := dl.Connect("canopy") deviceId, err := gocql.ParseUUID(flag.Arg(1)) if err != nil { fmt.Println("Error parsing UUID: ", flag.Arg(1), ":", err) return } _, err = conn.LookupDevice(deviceId) if err != nil { fmt.Println("Device not found: ", flag.Arg(1), ":", err) return } for i := 0; i < 100; i++ { //val := float64(i % 16); //t := time.Now().Add(time.Duration(-i)*time.Second) //err = device.InsertSensorSample(flag.Arg(2), t, val) //if err != nil { fmt.Println("Error inserting sample: ", err) //} } } else if flag.Arg(0) == "clear-sensor-data" { dl := cassandra_datalayer.NewDatalayer(cfg) conn, _ := dl.Connect("canopy") conn.ClearSensorData() } else if flag.Arg(0) == "test-email" { mailer, err := mail.NewMailClient(cfg) if err != nil { fmt.Println("Error initializing mail client: ", err) return } mail := mailer.NewMail() err = mail.AddTo(flag.Arg(1), "Customer") if err != nil { fmt.Println("Invalid recipient: ", flag.Arg(1), err) return } mail.SetSubject("Test email from Canopy") mail.SetHTML("<b>Canopy Rulez</b>") mail.SetFrom("*****@*****.**", "The Canopy Team") err = mailer.Send(mail) if err != nil { fmt.Println("Error sending email:", err) return } fmt.Println("Email sent.") } else if flag.Arg(0) == "migrate-db" { startVersion := flag.Arg(1) if startVersion == "" { fmt.Println("<startVersion> required") return } endVersion := flag.Arg(2) if endVersion == "" { fmt.Println("<endVersion> required") return } dl := cassandra_datalayer.NewDatalayer(cfg) err := dl.MigrateDB("canopy", startVersion, endVersion) if err != nil { fmt.Println(err.Error()) } } else if len(flag.Args()) == 0 { cmds[0].Perform(info) } else { fmt.Println("Unknown command '" + flag.Arg(0) + "'. See 'canopy-ops help'.") } }
func GET__api__device__id__var(info *RestRequestInfo, sideEffect *RestSideEffects) (map[string]interface{}, RestError) { deviceIdString := info.URLVars["id"] sensorName := info.URLVars["var"] authorized := false var device datalayer.Device uuid, err := gocql.ParseUUID(deviceIdString) if err != nil { return nil, URLNotFoundError() } //if info.Config.OptAllowAnonDevices() && device.PublicAccessLevel() > datalayer.NoAccess { device, err = info.Conn.LookupDevice(uuid) if err != nil { // TODO: What errors to return here? return nil, InternalServerError("Device lookup failed") } authorized = true //} else { // TODO: fix anon devices if info.Account == nil { return nil, NotLoggedInError() } device, err = info.Account.Device(uuid) if err != nil { // TODO: What errors to return here? return nil, InternalServerError("Device lookup failed") } authorized = true //} if !authorized { // TODO: What is the correct error for this? return nil, URLNotFoundError() } doc := device.SDDLDocument() if doc == nil { return nil, URLNotFoundError() } varDef, err := doc.LookupVarDef(sensorName) if err != nil { return nil, URLNotFoundError() } samples, err := device.HistoricData(varDef, time.Now(), time.Now().Add(-59*time.Minute), time.Now()) if err != nil { return nil, InternalServerError("Could not obtain sample data: " + err.Error()) } // Convert samples to JSON out := map[string]interface{}{} out["result"] = "ok" out["samples"] = []interface{}{} for _, sample := range samples { out["samples"] = append(out["samples"].([]interface{}), map[string]interface{}{ "t": sample.Timestamp.Format(time.RFC3339), "v": sample.Value, }) } return out, nil }