func (sm *SManager) open() {
	filename := "users.txt"
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		return  
	}
	f, err := os.Open(filename)
	if err != nil {
		log.Println("error opening file", err)
		return
	}
	defer f.Close()
	r := bufio.NewReaderSize(f, 4*1024)
	r.ReadLine()
	line, isPrefix, err := r.ReadLine()
	for err == nil && !isPrefix {
		s := string(line)
		if len(s) < 1 {  
			break
		}
		t := strings.Split(s, "\t")
		userName, dateRaw, pass := t[0], t[1], t[2]
		layout := "2006-01-02_15-04-05pm"
		date, err := time.Parse(layout, dateRaw)
		if err != nil {
			log.Println("error converting date: " + err.Error())
		}
		newUser := user{password: pass, dateRegistered: date}
		mgr.registeredUsers[userName] = newUser
		line, isPrefix, err = r.ReadLine()
	}
	if isPrefix {
		log.Println("buffer size to small")
		return
	}
	if err != io.EOF && err != nil {
		log.Println("not EOF", err)
		return
	}
}
open reads records from text file into memory
package sess
import (
	"bufio"
	b64 "encoding/base64"
	"io"
	"log"
	"math/rand"
	"os"
	"strings"
	"time"
	"golang.org/x/crypto/bcrypt"
)
type session struct {
	username   string
	browser    string
	ip         string
	lastActive time.Time
}
type user struct {
	password       string
	dateRegistered time.Time
}
type manage struct {
	activeSessions  map[string]session
	registeredUsers map[string]user
}
var mgr manage
type SManager string
func NewManager() *SManager {
	mgr = manage{
		activeSessions:  map[string]session{},
		registeredUsers: map[string]user{},
	}
	sm := SManager("")
	sm.open()
	return &sm
}
func (sm *SManager) RegisterUser(un, pw string) {
	newUser := user{password: pw, dateRegistered: time.Now()}
	mgr.registeredUsers[un] = newUser
}
func (sm *SManager) ValidateUser(id string) bool {
	_, ok := mgr.registeredUsers[id]
	return ok
}
func (sm *SManager) LoginSession(un, br, ipAddr string) string {
	s := &session{username: un, browser: br, ip: ipAddr, lastActive: time.Now()}
	id := ("random session id")  
	mgr.activeSessions[id] = *s
	return id
}
func (sm *SManager) UpdateSession(id string) {
	s := mgr.activeSessions[id]
	s.lastActive = time.Now()
	mgr.activeSessions[id] = s
}
func (sm *SManager) ShowSessions(userID string) []string {
	var str []string
	for _, s := range mgr.activeSessions {
		if s.username == userID {
			str = append(str, "Name: "+s.username+" IP: "+s.ip+" Time: "+s.lastActive.String())
		}
	}
	return str
}
func (sm *SManager) ShowUsers() []string {
	var str []string
	for k, s := range mgr.registeredUsers {
		str = append(str, k+"\tRegistered: "+s.dateRegistered.Format("2006-01-02 03:04pm"))
	}
	return str
}
func (sm *SManager) Close() {
	usersFile, err := os.Create("users.txt")
	if err != nil {
		log.Println("Cannot create new users.txt file", err)
		return
	}
	defer usersFile.Close()
	usersFile.WriteString("ID\tDate Registered\tHash\n")  
	for k, s := range mgr.registeredUsers {
		line := k + "\t" + s.dateRegistered.Format("2006-01-02_03-04-05pm") + "\t" + s.password + "\n"
		usersFile.WriteString(line)
	}
}