Example #1
0
// InfosSession get infos about the session (including remaining time)
func InfosSession(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	var resp InfosSessionResponse
	var session models.Session

	sid := handle.P.ByName("token")
	if sid == "" {
		return nil, tools.NewError(nil, 400, "bad request: missing token")
	}
	if tools.CheckID(sid) == false {
		return nil, tools.NewError(nil, 400, "bad request: invalid token")
	}

	session.IDFromHex(sid)
	err := session.Get(db)
	if err != nil {
		return nil, err
	}

	remaining := int(session.Expire - time.Now().Unix())
	if remaining <= 0 {
		return nil, tools.NewError(nil, 404, "not found: session is expired")
	}
	resp.Status = "ok"
	resp.Session.UserID = session.UserID.Hex()
	resp.Session.Domain = session.Domain
	resp.Session.Expire = session.Expire
	resp.Session.Remaining = remaining
	return resp, nil
}
Example #2
0
// Check if a session is expired, and if it grants access to the specified domain
func Check(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	var q CheckRequest

	err := rest.Parse(handle.R, &q)
	if err != nil {
		return nil, tools.NewError(err, 400, "bad request: couldn't parse body")
	}
	return CheckSession(q, db)
}
Example #3
0
// Logoff deletes a session (expired or not)
func Logoff(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	var session models.Session

	sid := handle.P.ByName("token")
	if sid == "" {
		return nil, tools.NewError(nil, 400, "bad request: missing token")
	}
	if tools.CheckID(sid) == false {
		return nil, tools.NewError(nil, 400, "bad request: invalid token")
	}
	session.IDFromHex(sid)

	err := session.Delete(db)
	if err != nil {
		return nil, err
	}

	return LogoffResponse{"ok"}, nil
}
Example #4
0
// Clean every expired sessions older than age
func Clean(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	sAge := handle.P.ByName("age")

	if sAge == "" {
		return nil, tools.NewError(nil, 400, "bad request: age is missing")
	}
	age, err := strconv.ParseInt(sAge, 10, 64)
	if err != nil {
		return nil, tools.NewError(err, 400, "bad request: invalid age")
	}
	n, err := models.CleanSessions(db, age)
	if err != nil {
		return nil, err
	}
	return CleanResponse{
		Status:  "ok",
		Deleted: n,
	}, nil
}
Example #5
0
// Delete a session in database
func (s *Session) Delete(db *mgo.DbQueue) error {
	n, err := db.Count("sessions", mgo.M{"_id": s.ID})
	if err != nil {
		return err
	}
	if n == 0 {
		return tools.NewError(nil, 404, "not found: session does not exist")
	}
	err = db.RemoveID("sessions", s.ID)
	return err
}
Example #6
0
// Delete user from database
func (u User) Delete(db *mgo.DbQueue) error {
	n, err := db.CountID("users", u.ID)
	if err != nil {
		return err
	}
	if n == 0 {
		return tools.NewError(nil, 404, "not found: user does not exist")
	}
	err = db.RemoveID("users", u.ID)
	return err
}
Example #7
0
func (u User) Login(username, password, domain string, lifespan int64, db *mgo.DbQueue) (Session, error) {
	var s Session
	var err error

	u.Username, err = govalidator.NormalizeEmail(username)
	if err != nil {
		return s, tools.NewError(nil, 400, "bad request: username must be a valid email")
	}
	u.Password = password
	if password == "" {
		return s, tools.NewError(nil, 400, "bad request: password is missing")
	}

	ok, err := u.Check(db)
	if err != nil {
		return s, err
	}
	if ok == false {
		return s, tools.NewError(nil, 403, "forbidden: invalid user or password")
	}
	if u.Enable == false {
		return s, tools.NewError(nil, 403, "forbidden: user is diabled")
	}
	ok = u.CheckDomain(domain)
	if ok == false {
		return s, tools.NewError(nil, 403, "forbidden: restricted domain")
	}

	s.UserID = u.ID
	s.Domain = domain
	_, err = s.Create(db, lifespan)
	if err != nil {
		return s, err
	}

	return s, nil
}
Example #8
0
// InfosUser returns informations about the user. It does not lists its sessions, yet (TODO)
func InfosUser(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	var user models.User

	uid := handle.P.ByName("uid")
	if handle.C.Public == true {
		ret, err := CheckSession(CheckRequest{
			Domain: "/io/konek/app/user",
			Token:  handle.Sid,
		}, db)
		if err != nil {
			return nil, err
		}
		sess := ret.(CheckResponse)
		if uid == "" {
			uid = sess.Session.UserID
		}
		if sess.Session.UserID != uid {
			return nil, tools.NewError(nil, 403, "forbiden: this is not your account")
		}
	}
	if tools.CheckID(uid) == false {
		return nil, tools.NewError(nil, 400, "bad request: invalid userID")
	}

	user.IDFromHex(uid)
	err := user.Get(db)
	if err != nil {
		return nil, err
	}
	user.Password = ""
	user.Salt = ""
	return InfosUserResponse{
		Status: "ok",
		Infos:  user,
	}, nil
}
Example #9
0
// Create a new user in database.
// (generates Salt)
func (u *User) Create(db *mgo.DbQueue) (bson.ObjectId, error) {
	n, err := db.Count("users", bson.M{"username": u.Username})
	if err != nil {
		return "", err
	}
	if n != 0 {
		return "", tools.NewError(nil, 409, "duplicate: user already exists")
	}

	u.ID = bson.NewObjectId()
	u.Salt, err = tools.GenSalt(12)
	if err != nil {
		return "", err
	}
	u.Password = tools.PasswordHash(u.Username, u.Password, u.Salt)
	err = db.Insert("users", u)
	return u.ID, err
}
Example #10
0
// Update user in database. (update salt and password if needed)
func (u User) Update(db *mgo.DbQueue) error {
	var user User

	err := db.FindOneID("users", &user, u.ID)
	if err != nil {
		return err
	}

	if u.Username != "" {
		if u.Password == "" {
			return tools.NewError(nil, 400, "bad request: need password to update username")
		}
		user.Username = u.Username
		user.Salt, err = tools.GenSalt(12)
		if err != nil {
			return err
		}
		user.Password = tools.PasswordHash(user.Username, u.Password, user.Salt)
	}
	if u.Password != "" {
		user.Salt, err = tools.GenSalt(12)
		if err != nil {
			return err
		}
		user.Password = tools.PasswordHash(user.Username, u.Password, user.Salt)
	}
	if u.Domains != nil {
		user.Domains = u.Domains
	}
	if u.Variables != nil {
		user.Variables = u.Variables
	}
	user.Enable = u.Enable

	err = db.Push(func(db *mgo.Database, ec chan error) {
		ec <- db.C("users").UpdateId(u.ID, user)
	})
	return err
}
Example #11
0
// CreateUser create a new user. Checks for duplicate users and password-length requirement
func CreateUser(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	var user models.User

	user.Enable = true
	user.Domains = nil
	user.Variables = nil
	err := rest.Parse(handle.R, &user)
	if err != nil {
		return nil, tools.NewError(err, 400, "bad request: couldn't parse body")
	}

	if user.Username == "" {
		return nil, tools.NewError(nil, 400, "bad request: username is missing")
	}
	if user.Password == "" {
		return nil, tools.NewError(nil, 400, "bad request: password is missing")
	}
	if len(user.Password) < handle.C.PasswordMinLength {
		return nil, tools.NewError(nil, 400, "bad request: password is too short")
	}
	if user.Domains == nil || len(user.Domains) == 0 {
		return nil, tools.NewError(nil, 400, "bad request: domains is missing")
	}
	if user.Variables == nil {
		user.Variables = make(map[string]interface{})
	}
	if govalidator.IsEmail(user.Username) == false {
		return nil, tools.NewError(nil, 400, "bad request: username must be a valid email")
	}

	user.Username, err = govalidator.NormalizeEmail(user.Username)
	if err != nil {
		return nil, tools.NewError(nil, 400, "bad request: username must be a valid email")
	}
	uid, err := user.Create(db)
	return CreateResponse{
		Status: "ok",
		UserID: uid.Hex(),
	}, err
}
Example #12
0
func CheckSession(q CheckRequest, db *mgo.DbQueue) (interface{}, error) {
	var resp CheckResponse
	var session models.Session

	if q.Token == "" {
		return nil, tools.NewError(nil, 400, "bad request: token is missing")
	}
	if tools.CheckID(q.Token) == false {
		return nil, tools.NewError(nil, 400, "bad request: invalid token")
	}
	if q.Domain == "" {
		return nil, tools.NewError(nil, 400, "bad request: domain is missing")
	}
	if q.Domain == "/" {
		return nil, tools.NewError(nil, 400, "bad request: illegal domain")
	}

	session.IDFromHex(q.Token)
	err := session.Get(db)
	if err != nil {
		return nil, err
	}

	if session.Expire < time.Now().Unix() {
		return nil, tools.NewError(nil, 404, "not found: session is expired")
	}

	if tools.CheckDomain(q.Domain, session.Domain) == false {
		return nil, tools.NewError(nil, 403, "forbidden: restricted domain")
	}

	resp.Status = "ok"
	resp.Session.UserID = session.UserID.Hex()
	resp.Session.Expire = session.Expire
	resp.Session.Remaining = int(session.Expire - time.Now().Unix())

	return resp, nil
}
Example #13
0
// Login a user, creating a new session.
func Login(handle tools.Handle, db *mgo.DbQueue) (interface{}, error) {
	var q LoginRequest
	var user models.User
	var session models.Session
	var resp LoginResponse

	err := rest.Parse(handle.R, &q)
	if err != nil {
		return nil, tools.NewError(err, 400, "bad request: couldn't parse body")
	}

	if q.Domain == "" {
		return nil, tools.NewError(nil, 400, "bad request: domain is missing")
	}
	if q.Domain == "/" {
		return nil, tools.NewError(nil, 400, "bad request: illegal domain")
	}

	if q.Username == "" {
		return nil, tools.NewError(nil, 400, "bad request: username is missing")
	}
	if q.Password == "" {
		return nil, tools.NewError(nil, 400, "bad request: password is missing")
	}

	user.Username = q.Username
	user.Password = q.Password

	if govalidator.IsEmail(user.Username) == false {
		return nil, tools.NewError(nil, 400, "bad request: username must be a valid email")
	}

	user.Username, err = govalidator.NormalizeEmail(user.Username)
	if err != nil {
		return nil, tools.NewError(nil, 400, "bad request: username must be a valid email")
	}

	ok, err := user.Check(db)
	if err != nil {
		return nil, err
	}
	if ok == false {
		return nil, tools.NewError(nil, 403, "forbidden: invalid user or password")
	}
	if user.Enable == false {
		return nil, tools.NewError(nil, 403, "forbidden: user is diabled")
	}
	ok = user.CheckDomain(q.Domain)
	if ok == false {
		return nil, tools.NewError(nil, 403, "forbidden: restricted domain")
	}

	session.UserID = user.ID
	session.Domain = q.Domain
	remaining, err := session.Create(db, handle.C.SessionLifespan)
	if err != nil {
		return nil, err
	}
	resp.Status = "ok"
	resp.Session.Token = session.ID.Hex()
	resp.Session.UserID = session.UserID.Hex()
	resp.Session.Expire = session.Expire
	resp.Session.Remaining = remaining
	return resp, nil
}