Example #1
0
func (s *Store) Clean(inactive time.Duration) error {
	locker.Lock("clean")
	defer locker.Unlock("clean")

	rows, err := s.Query(`
		SELECT id, value
		FROM `+SqlTableName+`
		WHERE key = $1
	`, SessionLastUpdated)
	if err != nil {
		return err
	}
	defer rows.Close()

	cutoff := time.Now().UTC().Add(-inactive)
	for rows.Next() {
		var id []byte
		var last string
		if err := rows.Scan(&id, &last); err != nil {
			return err
		}
		lastUp, err := time.Parse(time.RFC3339Nano, last)
		if err != nil {
			return err
		}
		if lastUp.Before(cutoff) {
			_, err = s.Exec(
				"DELETE FROM "+SqlTableName+" WHERE id = $1", id)
			if err != nil {
				return err
			}
		}
	}
	return rows.Err()
}
Example #2
0
func manageCollaborators(w *web) {
	var form struct {
		ProjectName   string
		Collaborators []string
	}
	w.decode(&form)
	proj := getProject(w.user, w.user.Id, form.ProjectName)

	// We need to do a delete followed by an insert, which means we need
	// exclusion for this project to prevent race conditions.
	lockKey := fmt.Sprintf("%s-%s", proj.Name, proj.Owner.Id)
	locker.Lock(lockKey)
	defer locker.Unlock(lockKey)

	csql.Tx(db, func(tx *sql.Tx) {
		csql.Exec(tx, `
			DELETE FROM
				collaborator
			WHERE
				project_owner = $1 AND project_name = $2
		`, proj.Owner.Id, proj.Name)
		for _, collaborator := range form.Collaborators {
			u := findUserById(collaborator)
			csql.Exec(tx, `
				INSERT INTO collaborator
					(project_owner, project_name, userid)
				VALUES
					($1, $2, $3)
			`, proj.Owner.Id, proj.Name, u.Id)
		}
	})

	w.json(w.r.PostForm)
}
Example #3
0
// Set associates the plain text password given with the user that is uniquely
// identified by id. The password is hashed with bcrypt. If there is a problem
// with hashing or with storing the password, an error is returned.
//
// This may be called on a new user.
func (s *Store) Set(id, password string) (cerr error) {
	defer csql.Safe(&cerr)

	hash, err := bcrypt.GenerateFromPassword(
		[]byte(password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}

	// This lock can be avoided if we use some sort of upsert.
	// It's possible with Postgres, but this is just way easier.
	locker.Lock(id)
	defer locker.Unlock(id)

	n := csql.Count(s, `
		SELECT COUNT(*) FROM `+SqlTableName+` WHERE id = $1
		`, id)
	if n == 0 {
		csql.Exec(s, `
			INSERT INTO `+SqlTableName+` (id, hash) VALUES ($1, $2)
			`, id, hash)
	} else {
		csql.Exec(s, `
			UPDATE `+SqlTableName+` SET id = $1, hash = $2 WHERE id = $1
			`, id, hash)
	}
	return nil
}
Example #4
0
func Lock(sess *sessions.Session)    { locker.Lock(sess.ID) }
Example #5
0
func (user *lcmUser) lock() {
	locker.Lock(user.Id)
}