Beispiel #1
0
func userLoginHandler(cmd *CmdMessage) error {
	data := make(map[string]interface{})
	email, ok1 := cmd.Data["email"].(string)
	pass, ok2 := cmd.Data["password"].(string)

	if !(ok1 && ok2) {
		return errors.New("Login failed: missing email or password")
	}

	ClearOldSessions()

	user := &db.User{}

	err := db.C("users").Find(bson.M{"email": email, "password": pass}).One(user)

	if err != nil {
		return errors.New("Login failed: bad email or password")
	}

	// creating the session
	sess := &db.Session{UId: user.Id, Created: time.Now().Unix()}
	sess.GenId()
	db.C("sessions").Insert(sess)

	data["session_id"] = sess.Id.Hex()
	data["id"] = user.Id.Hex()
	data["org_id"] = user.OrgId.Hex()

	cmd.Conn.owner.Authenticate(user.Id)
	return DispatchMessage("login", data, cmd.Conn)
}
func Test_daemonLoginHandler(t *testing.T) {
	// when there is a daemon -----------------------------------------
	tmpD := &db.Daemon{
		Id:       bson.ObjectIdHex("52a4ed348350a921bd000001"),
		OrgId:    bson.ObjectIdHex("52a4ed348350a921bd000002"),
		Name:     "daemon",
		Password: "******",
	}
	db.AddTemp("daemons", tmpD)

	// a field missing
	lcmd := &CmdMessage{
		Data: make(map[string]interface{}),
		Conn: &Connection{owner: &Daemon{}},
	}
	lcmd.Data["org_id"] = "52a4ed348350a921bd000002"
	lcmd.Data["name"] = "daemon"

	err := LoginHandler(lcmd)

	test.Assert(err != nil, "it sends an error if there is a field missing", t)

	// wrong password
	lcmd.Data["password"] = "******"

	err = LoginHandler(lcmd)

	test.Assert(err != nil, "it sends an error if password is wrong", t)

	// all correct
	lcmd.Data["password"] = "******"

	err = LoginHandler(lcmd)

	cmd := GetLastCmd()
	test.Assert(cmd.Data["id"].(string) == "52a4ed348350a921bd000001", "it returns a daemon id", t)
	test.Assert(err == nil, "it does not throw an error", t)
	test.Assert(lcmd.Conn.owner.(*Daemon).Entry != nil, "it extracts the database information and puts it on the connection", t)

	db.DelTemps("daemons")

	// when there is no daemon ----------------------------------------
	err = LoginHandler(lcmd)

	test.Assert(err == nil, "it does not throw an error", t)
	cmd = GetLastCmd()
	err = db.C("daemons").FindId(bson.ObjectIdHex(cmd.Data["id"].(string))).One(tmpD)
	test.Assert(err == nil, "it creates a new daemon, if one does not exist", t)
	test.Assert(tmpD.Status == "NOT_KNOWN", "the daemon is set as unknown", t)

	db.C("daemons").RemoveId(bson.ObjectIdHex(cmd.Data["id"].(string)))
}
Beispiel #3
0
func daemonLoginHandler(cmd *CmdMessage) error {
	data := make(map[string]interface{})
	name, ok1 := cmd.Data["name"].(string)
	pass, ok2 := cmd.Data["password"].(string)
	orgId, ok3 := cmd.Data["org_id"].(string)

	if !(ok1 && ok2 && ok3) {
		return errors.New("Login failed: missing name or password or org_id")
	}

	if !bson.IsObjectIdHex(orgId) {
		return errors.New("Organisation ID is invalid")
	}

	daemon := &db.Daemon{}

	err := db.C("daemons").Find(bson.M{
		"name":     name,
		"password": pass,
		"org_id":   bson.ObjectIdHex(orgId),
	}).One(daemon)

	if err != nil {
		err = db.C("daemons").Find(bson.M{
			"name":   name,
			"org_id": bson.ObjectIdHex(orgId),
		}).One(daemon)
		// if there is a mistake in password then it is an error
		if err == nil {
			return errors.New("Login failed: bad password")
		}
		// otherwise we have to create a new entry
		daemon = &db.Daemon{
			Name:     name,
			Password: pass,
			OrgId:    bson.ObjectIdHex(orgId),
			Status:   "NOT_KNOWN",
		}
		daemon.GenId()
		db.C("daemons").Insert(daemon)
	}

	data["id"] = daemon.Id.Hex()

	cmd.Conn.owner.Authenticate(daemon.Id)
	DispatchMessage("login", data, cmd.Conn)
	return nil
}
func storeMonitoringData(cmd *CmdMessage) error {
	// creating a new data point
	list, ok := cmd.Data["list"].([]interface{})
	if !ok {
		return errors.New("A list of parameters is not specified")
	}

	c := db.C("monitoring_of_" + cmd.Conn.owner.(*Daemon).Id)
	for _, e := range list {
		entry, ok1 := e.(map[string]interface{})
		if !ok1 {
			return errors.New("Monitoring entry is invalid")
		}
		parameter, ok2 := entry["parameter"].(string)
		values, ok3 := entry["values"].(map[string]interface{})
		if !(ok2 && ok3) {
			return errors.New("You need to specify parameter and values")
		}

		for t, v := range values {
			time, _ := strconv.Atoi(t)
			value, ok := v.(float64)
			if !ok {
				return errors.New("Non floating point number value supplied")
			}
			c.Insert(bson.M{
				"parameter": parameter,
				"time":      time,
				"value":     value,
			})
		}
	}

	return nil
}
func Test_MonitoringHandlerUser(t *testing.T) {
	// before
	user := &User{OrgId: "Anonymous"}
	daemon := &Daemon{Id: "a", OrgId: "Anonymous"}
	user.Authorise()

	data1 := &db.Data{"", "cpu", 1000, 12.5}
	data2 := &db.Data{"", "cpu", 1500, 14.5}
	data3 := &db.Data{"", "cpu", 1600, 15.5}
	data4 := &db.Data{"", "cpu", 1900, 11.5}
	data5 := &db.Data{"", "ram", 1200, 9000}
	db.AddTemp("monitoring_of_a", data1)
	db.AddTemp("monitoring_of_a", data2)
	db.AddTemp("monitoring_of_a", data3)
	db.AddTemp("monitoring_of_a", data4)
	db.AddTemp("monitoring_of_a", data5)

	// let's try it from the string...
	msg := &Message{
		msg: `
        {
            "type": "monitoring",
            "data": {
                "daemon_id": "a",
                "parameter": "cpu",
                "from": 1100,
                "to": 1600
            }
        }
        `,
		c: &Connection{owner: user},
	}

	// the daemon is not in the org
	err, _ := HandleMsg(msg)

	test.Assert(err != nil, "it doesn't allow to monitor foreign daemons", t)

	// daemon exists in the org
	daemon.Authorise()

	err, _ = HandleMsg(msg)

	cmd := GetLastCmd()

	test.Assert(err == nil, "it does allow to monitor your daemons", t)
	vals := cmd.Data["values"].(map[string]float64)
	test.Assert(len(vals) == 2, "it returns the right number of answers", t)
	test.Assert(vals["1500"] == 14.5, "it has the correct data", t)
	test.Assert(vals["1600"] == 15.5, "it has the correct data", t)

	// cleaning up
	db.C("monitoring_of_a").DropCollection()
	user.Deauthorise()
	daemon.Deauthorise()
}
Beispiel #6
0
//-------------------------------------------------------
// methods
//-------------------------------------------------------
// obtain all the data and proceed to authorisation
func (d *Daemon) Authenticate(id bson.ObjectId) error {
	c := db.C("daemons")
	err := c.FindId(id).One(&d.Entry)
	if err == nil {
		d.Id = id.Hex()
		d.OrgId = d.Entry.OrgId.Hex()
		return d.Authorise()
	}
	return err
}
Beispiel #7
0
//-------------------------------------------------------
// methods
//-------------------------------------------------------
// obtain all the data and proceed to authorisation
func (u *User) Authenticate(id bson.ObjectId) error {
	c := db.C("users")
	err := c.FindId(id).One(&u.Entry)
	if err == nil {
		u.Id = id.Hex()
		u.OrgId = u.Entry.OrgId.Hex()
		return u.Authorise()
	}
	return err
}
func Test_userLoginHandler(t *testing.T) {
	tmpU := &db.User{Id: bson.ObjectIdHex("52a4ed348350a921bd000001"),
		OrgId: bson.ObjectIdHex("52a4ed348350a921bd000002"), Email: "*****@*****.**", Password: "******"}
	db.AddTemp("users", tmpU)

	// no password
	lcmd := &CmdMessage{Data: make(map[string]interface{}), Conn: &Connection{owner: &User{}}}
	lcmd.Data["email"] = "*****@*****.**"

	err := LoginHandler(lcmd)

	test.Assert(err != nil, "it sends an error if there is no password", t)

	// wrong password
	lcmd.Data["password"] = "******"

	err = LoginHandler(lcmd)

	test.Assert(err != nil, "it sends an error if password is wrong", t)

	// all correct
	lcmd.Data["password"] = "******"

	err = LoginHandler(lcmd)

	cmd := GetLastCmd()
	test.Assert(len(cmd.Data["session_id"].(string)) == 24, "it returns a session_id for this user", t)
	test.Assert(err == nil, "it does not throw an error", t)
	test.Assert(cmd.Data["id"].(string) == "52a4ed348350a921bd000001", "it returns a user id", t)
	session := &db.Session{}
	err = db.C("sessions").Find(bson.M{"_id": bson.ObjectIdHex(cmd.Data["session_id"].(string))}).One(session)
	test.Assert(err == nil, "it creates a session in the database", t)
	test.Assert(lcmd.Conn.owner.(*User).Entry != nil, "it extracts the database information and puts it on the connection", t)

	db.DelTemps("users")
	db.C("sessions").RemoveAll(bson.M{"uid": bson.ObjectIdHex("52a4ed348350a921bd000001")})

	// no user at all
	err = LoginHandler(lcmd)

	test.Assert(err != nil, "it sends an error if there is no such user", t)
}
Beispiel #9
0
// removes all the stub data from the database
func cleanTheDB() {
	fmt.Println("Cleaning up the DB, don't turn off...")
	// delete all the users
	db.DelTemps("users")
	// all the monitoring information
	for _, d := range daemons {
		db.C("monitoring_of_" + d.Id.Hex()).DropCollection()
	}
	// all the daemons
	db.DelTemps("daemons")
	// all the orgs
	db.DelTemps("organisations")
	fmt.Println("Bye!")
}
func Test_LogoutHandler(t *testing.T) {
	// a user is removed from the organisation
	// and his session is deleted
	tmpS := &db.Session{UId: bson.ObjectIdHex("52a4ed348350a921bd000001")}
	db.AddTemp("sessions", tmpS)

	user := &User{
		Id:        "52a4ed348350a921bd000001",
		SessionId: tmpS.GetId().Hex(),
		OrgId:     "Anonymous",
	}
	msg := &Message{
		msg: `{"type":"logout","data":{}}`,
		c:   &Connection{owner: user},
	}
	user.Authorise()

	test.Assert(user.IsAuthorised(), "user is authorised before logout", t)

	err, _ := HandleMsg(msg)

	test.Assert(err == nil, "it logs out successfully", t)
	test.Assert(!user.IsAuthorised(), "user is not in the organisation any more", t)
	err = db.C("sessions").Find(bson.M{
		"uid": bson.ObjectIdHex("52a4ed348350a921bd000001"),
	}).One(tmpS)
	test.Assert(err != nil, "there are no sessions for this user", t)

	// it does not break if session was already gone
	err, _ = HandleMsg(msg)
	test.Assert(err == nil, "it does not blow up without session", t)

	// a daemon is removed from the organisation
	daemon := &Daemon{
		Id:    "52a4ed348350a921bd000001",
		OrgId: "Anonymous",
	}
	msg = &Message{
		msg: `{"type":"logout","data":{}}`,
		c:   &Connection{owner: daemon},
	}
	daemon.Authorise()

	test.Assert(daemon.IsAuthorised(), "daemon is authorised before logout", t)

	err, _ = HandleMsg(msg)

	test.Assert(err == nil, "it logs out successfully", t)
	test.Assert(!daemon.IsAuthorised(), "daemon is not in the organisation any more", t)
}
Beispiel #11
0
// a handler that deauthorises the user or the daemon
func LogoutHandler(cmd *CmdMessage) error {
	data := make(map[string]interface{})
	cmd.Conn.owner.Deauthorise()

	// if it is user, delete the session
	if cmd.Conn.owner.IsUser() {
		db.C("sessions").RemoveAll(bson.M{
			"uid": bson.ObjectIdHex(cmd.Conn.owner.(*User).Id),
		})
	}

	data["status"] = "OK"
	DispatchMessage("logout", data, cmd.Conn)
	return nil
}
// a handler that either stores monitoring information
// for that particular daemon, or sends the stats to the user
func MonitoringHandler(cmd *CmdMessage) error {
	if !cmd.Conn.owner.IsAuthorised() {
		return errors.New("Logging in is required before using this handler")
	}
	if !cmd.Conn.owner.IsUser() {
		return storeMonitoringData(cmd)
	}

	daemonId, ok := cmd.Data["daemon_id"].(string)
	if !ok {
		return errors.New("wrong daemon_id supplied")
	}

	daemons := cmd.Conn.owner.GetOrg().Daemons
	_, ok = daemons[daemonId]
	if !ok {
		return errors.New("daemon not found")
	}

	param, ok1 := cmd.Data["parameter"].(string)
	from, ok2 := cmd.Data["from"].(float64)
	to, ok3 := cmd.Data["to"].(float64)

	if !(ok1 && ok2 && ok3) {
		return errors.New("Some parameters are missing!")
	}

	c := db.C("monitoring_of_" + daemonId)
	var inf []db.Data = nil

	c.Find(bson.M{
		"time":      bson.M{"$gte": from, "$lte": to},
		"parameter": param,
	}).All(&inf)

	vals := make(map[string]float64)

	for _, d := range inf {
		vals[strconv.FormatInt(d.Time, 10)] = d.Value
	}

	data := make(map[string]interface{})
	data["daemon_id"] = daemonId
	data["parameter"] = param
	data["values"] = vals

	return DispatchMessage("monitoring", data, cmd.Conn)
}
Beispiel #13
0
func daemonUpdateInfo(cmd *CmdMessage) error {
	platform, ok1 := cmd.Data["daemon_platform"].(string)
	par, ok2 := cmd.Data["daemon_all_parameters"].([]interface{})
	mon, ok3 := cmd.Data["daemon_monitored_parameters"].([]interface{})

	if !(ok1 && ok2 && ok3) {
		return errors.New("All parameters must be supplied")
	}

	parameters, err1 := ToStringSlice(par)
	monitored, err2 := ToStringSlice(mon)

	if err1 != nil || err2 != nil {
		return errors.New("Non-string parameters given")
	}

	// update elements for this id
	daemon := cmd.Conn.owner.(*Daemon)
	db.C("daemons").UpdateId(daemon.Entry.Id, bson.M{
		"$set": bson.M{
			"platform":   platform,
			"parameters": parameters,
			"monitored":  monitored,
		},
	})

	// update them on the daemon itself
	daemon.Entry.Platform = platform
	daemon.Entry.Parameters = parameters
	daemon.Entry.Monitored = monitored

	// send information to all the users in the org
	for _, ucon := range daemon.GetOrg().Users {
		err := sendDaemonMessage(daemon, ucon)
		if err != nil {
			return err
		}
	}

	return nil
}
Beispiel #14
0
//-------------------------------------------------------
// helper functions
//-------------------------------------------------------
// get the id from the session and proceed to authentication
func AuthFromSession(sessId string) (bson.ObjectId, error) {
	c := db.C("sessions")
	result := &db.Session{}
	err := c.FindId(bson.ObjectIdHex(sessId)).One(result)
	return result.UId, err
}
func Test_MonitoringHandlerDaemon(t *testing.T) {
	daemon := &Daemon{Id: "a", OrgId: NO_ORG, Entry: &db.Daemon{}}

	msg := &Message{
		msg: `{
            "type": "monitoring",
            "data": {
                "list": [{
                    "parameter": "cpu",
                    "values": {
                        "1104699": 12.5
                    }
                }]
            }
        }`,
		c: &Connection{owner: daemon},
	}

	// without authorisation
	err, _ := HandleMsg(msg)

	test.Assert(err != nil, "the daemon must be authorised", t)

	// with authorisation
	daemon.OrgId = "Anonymous"
	daemon.Authorise()

	err, _ = HandleMsg(msg)

	test.Assert(err == nil, "it does not throw errors, when the daemon is authorised", t)
	data := &db.Data{}
	db.C("monitoring_of_a").Find(bson.M{"parameter": "cpu"}).One(data)
	test.Assert(data.Time == 1104699, "it stores the time right", t)
	test.Assert(data.Value == 12.5, "it stores the metric right", t)

	// adding additional metrics to it
	msg.msg = `{
        "type": "monitoring",
        "data": {
            "list": [{
                "parameter": "cpu",
                "values": {
                    "1104670": 15
                }
            }]
        }
    }`

	err, _ = HandleMsg(msg)

	test.Assert(err == nil, "it still doesn't throw errors", t)
	q := db.C("monitoring_of_a").Find(bson.M{"parameter": "cpu"})
	count, err := q.Count()
	test.Assert(count == 2, "it returns additional values", t)
	q.Sort("time").One(data)
	test.Assert(data.Time == 1104670, "it stores the time right", t)
	test.Assert(data.Value == 15, "it stores the metric right", t)

	// cleaning up
	db.C("monitoring_of_a").DropCollection()
	daemon.Deauthorise()
}
Beispiel #16
0
// remove all old sessions
func ClearOldSessions() {
	expired := time.Now().Unix() - 10*24*60*60
	db.C("sessions").Remove(bson.M{"created": bson.M{"$ls": expired}})
}
func Test_DaemonHandler(t *testing.T) {
	user := &User{
		Id:    "52a4ed348350a921bd000001",
		OrgId: NO_ORG,
	}
	lcmd := &CmdMessage{
		Data: make(map[string]interface{}),
		Conn: &Connection{owner: user},
	}
	lcmd.Data["daemon_id"] = "a"
	daemon := &Daemon{
		Id:    "a",
		OrgId: "Random_org",
		c:     &Connection{},
		Entry: &db.Daemon{},
	}
	daemon.c.owner = daemon
	daemon.Authorise()

	// user has to be authorised, to get daemons data
	err := DaemonHandler(lcmd)
	test.Assert(err != nil, "user has to be authorised", t)

	// if the daemon does not exist, then an error is returned
	user.OrgId = "Anonymous"
	user.Authorise()

	err = DaemonHandler(lcmd)
	test.Assert(err != nil, "the daemon has to exist in the org", t)

	// if everything is ok, the daemon information is returned
	daemon.Deauthorise()
	daemon.OrgId = "Anonymous"
	daemon.Authorise()

	err = DaemonHandler(lcmd)
	test.Assert(err == nil, "it does not send the error", t)

	cmd := GetLastCmd()
	test.Assert(cmd.Data["daemon_id"].(string) == "a", "it returns the daemon information", t)

	//--------------------------------------------------
	// if it is a daemon
	//--------------------------------------------------
	// not sending the data
	msg := &Message{
		msg: `{"type":"daemon","data":{"daemon_id":"id of the daemon"}}`,
		c:   &Connection{owner: daemon},
	}

	err, _ = HandleMsg(msg)
	test.Assert(err != nil, "it has to contain information", t)

	// when the data is sent, it stores it in the database
	msg.msg = `{
        "type":"daemon",
        "data":{
            "daemon_id":"id of the daemon",
            "daemon_platform":"Linux",
            "daemon_all_parameters":["cpu","ram","network"],
            "daemon_monitored_parameters":["cpu","ram"]
        }
    }`

	tmpD := &db.Daemon{OrgId: bson.ObjectIdHex("52a4ed348350a921bd000002"), Name: "a", Password: "******"}
	db.AddTemp("daemons", tmpD)
	daemon.Entry = tmpD
	daemon.Id = tmpD.Id.Hex()

	err, _ = HandleMsg(msg)
	test.Assert(err == nil, "no errors are raised", t)
	dbd := &db.Daemon{}
	db.C("daemons").FindId(tmpD.Id).One(dbd)
	test.Assert(dbd.Platform == "Linux", "it stores the platform in the database", t)
	test.Assert(len(dbd.Parameters) == 3, "it stores all the parameters", t)
	test.Assert(len(dbd.Monitored) == 2, "it also stores what it is monitoring", t)

	// it also sends new information to all the users in the org
	cmd = GetLastCmd()
	test.Assert(cmd.Type == "daemon", "it sends a daemon message", t)
	test.Assert(cmd.Data["daemon_id"].(string) == daemon.Id, "with the latest information about this daemon", t)

	// cleaning up
	daemon.Deauthorise()
	user.Deauthorise()
	db.DelTemps("daemons")
}