Beispiel #1
0
func (h *Handler) handleUpdate(w http.ResponseWriter, r *http.Request) {
	_, err := session.Parse(r)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	path := config.Get("invoice_data")
	v, err := invoice.Load(path)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	key := r.FormValue("key")
	hours, _ := strconv.Atoi(r.FormValue("hours"))

	v.SetHours(key, hours)
	err = v.Save(path)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	url := r.FormValue("url")
	if url == "" {
		url = config.Get("baseurl")
	}

	http.Redirect(w, r, url, http.StatusFound)
}
Beispiel #2
0
func allowed() bool {
	if check {
		ok := strings.ToLower(config.Get("logging"))
		allow = (ok == "true" || ok == "on" || ok == "1")
		header = config.Get("response_header")
		check = false
	}
	return allow
}
Beispiel #3
0
func main() {
	switch len(os.Args) {
	case 1:
		break
	case 2:
		err := os.Chdir(os.Args[1])
		if err != nil {
			panic(err)
		}
		break
	default:
		return
	}

	err := config.Load("./data/data.db")
	if err != nil {
		panic(err)
	}

	allow, _ := strconv.ParseBool(config.Get("archive_migrate"))
	if allow != true {
		fmt.Println("Migrate not allowed in this environment")
		return
	}

	config.Dump(os.Stdout)

	m, err := getData()
	if err != nil {
		panic(err)
	}

	invoiceData := config.Get("invoice_data")
	fmt.Printf("=> %s\n", invoiceData)
	m.Invoice.Save(invoiceData)

	archivePath := config.Get("archive_path")
	err = os.RemoveAll(archivePath)
	if err != nil {
		panic(err)
	}

	err = os.MkdirAll(archivePath, 0755)
	if err != nil {
		panic(err)
	}

	for _, a := range m.Archive {
		err = saveFile(a.Url, filepath.Join(archivePath, a.Name))
		if err != nil {
			fmt.Println(err.Error())
		}
	}

	fmt.Println("OK")
}
Beispiel #4
0
func (h *Handler) serveNotFound(w http.ResponseWriter, r *http.Request) {
	m := map[string]interface{}{
		"baseurl": config.Get("baseurl"),
	}
	w.WriteHeader(http.StatusNotFound)
	h.Templates.ExecuteTemplate(w, "error404.html", m)
}
Beispiel #5
0
func (h *Handler) serveServerError(w http.ResponseWriter, r *http.Request) {
	m := map[string]interface{}{
		"baseurl": config.Get("baseurl"),
	}
	w.WriteHeader(http.StatusInternalServerError)
	h.Templates.ExecuteTemplate(w, "error500.html", m)
}
Beispiel #6
0
func (h *Handler) handleHome(w http.ResponseWriter, r *http.Request) {
	s, _ := session.Parse(r)
	if s != nil {
		s.Save(w, true)
	}

	v, err := invoice.Load(config.Get("invoice_data"))
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	urlpath := strings.Trim(r.URL.Path, "/")
	segments := strings.Split(urlpath, "/")

	if len(segments) == 2 {
		v.SetSelected(segments[1])
	}

	msg, _ := flashdata.Get(w, r)

	m := map[string]interface{}{
		"Hours":    make([]int, 25),
		"Invoice":  v,
		"LoggedIn": s != nil,
		"Message":  msg,
		"Url":      r.URL.Path,
	}

	h.Templates.ExecuteTemplate(w, "home.html", m)
}
Beispiel #7
0
func Row(q string, params []interface{}, bind []interface{}) error {
	db, err := sql.Open("sqlite3", config.Get("dbf"))
	if err != nil {
		return err
	}
	defer db.Close()

	stmt, err := db.Prepare(q)
	if err != nil {
		return err
	}
	defer stmt.Close()

	row := stmt.QueryRow(params...)
	if err != nil {
		return err
	}

	err = row.Scan(bind...)
	if err != nil {
		return err
	}

	return nil
}
Beispiel #8
0
func Parse(r *http.Request) (*Session, error) {
	c, err := r.Cookie(config.Get("session_cookie_name"))
	if err != nil {
		return nil, err
	}

	q := `
        SELECT
            id
            , key
        FROM user_session s
        WHERE s.key = ?
        AND s.valid_until > ?;
    `

	params := []interface{}{
		c.Value,
		time.Now().Unix(),
	}

	s := new(Session)

	bind := []interface{}{
		&s.Id,
		&s.Key,
	}

	err = dao.Row(q, params, bind)
	if err != nil {
		return nil, err
	}

	return s, nil
}
Beispiel #9
0
func loadTemplates() {
	if Templates == nil {
		t, _ := template.ParseGlob(
			filepath.Join(config.Get("email"), "*.*"))
		Templates = t
	}
}
Beispiel #10
0
func New() (*Handler, error) {
	h := new(Handler)

	h.header = config.Get("response_header")

	h.Rules = []*Rule{
		&Rule{"GET:/hightech", nil, h.handleHome},
		&Rule{"GET:/hightech/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]", nil, h.handleHome},
		&Rule{"GET:/hightech/pull", nil, h.handlePull},
		&Rule{"GET:/hightech/purge", nil, h.handlePurge},
		&Rule{"GET:/hightech/verify/[A-Za-z0-9][A-Za-z0-9-]*", nil, h.handleVerify},
		&Rule{"POST:/hightech/close", nil, h.handleClose},
		&Rule{"POST:/hightech/update", nil, h.handleUpdate},
		&Rule{"POST:/hightech/verify", nil, h.handleVerifyPost},
	}

	// Compile rules
	for _, rule := range h.Rules {
		re, err := regexp.Compile(fmt.Sprintf("^%s$",
			strings.TrimRight(rule.Pattern, "/")))
		if err != nil {
			panic(err)
		}
		rule.Compiled = re
	}

	err := h.loadTemplates()
	if err != nil {
		return nil, err
	}

	return h, nil
}
Beispiel #11
0
func Set(w http.ResponseWriter, s string) {
	secure, _ := strconv.ParseBool(config.Get("session_cookie_secure"))

	c := new(http.Cookie)
	c.Name = fmt.Sprintf("%s-flash", config.Get("session_cookie_name"))
	c.Path = config.Get("session_cookie_path")
	c.Value = base64.URLEncoding.EncodeToString([]byte(strings.TrimSpace(s)))
	if c.Value != "" {
		c.MaxAge = 0
	} else {
		c.MaxAge = -1
	}
	c.Secure = secure

	http.SetCookie(w, c)
	logger.Log(w, "SET-COOKIE", c.String())
}
Beispiel #12
0
func (s *Session) Save(w http.ResponseWriter, keepalive bool) error {
	q := `
        UPDATE user_session SET
            valid_until = ?
            , modified_date = ?
        WHERE id = ?;
    `

	valid := int64(0)

	if keepalive {
		valid = time.Now().Unix() + SESSION_OFFSET
	}

	params := []interface{}{
		valid,
		time.Now().Unix(),
		s.Id,
	}

	_, err := dao.Exec(q, params)
	if err != nil {
		return err
	}

	expires := -1

	if keepalive {
		expires, _ = strconv.Atoi(config.Get("session_cookie_expires"))
	}

	secure, _ := strconv.ParseBool(config.Get("session_cookie_secure"))

	c := new(http.Cookie)
	c.Name = config.Get("session_cookie_name")
	if keepalive {
		c.Value = s.Key
	}
	c.Path = config.Get("session_cookie_path")
	c.MaxAge = expires
	c.Secure = secure

	http.SetCookie(w, c)
	logger.Log(w, "SET-COOKIE", c.String())
	return nil
}
Beispiel #13
0
func (h *Handler) loadTemplates() error {
	t, err := template.ParseGlob(filepath.Join(config.Get("templates"), "*.*"))
	if err != nil {
		return err
	}

	h.Templates = t

	return nil
}
Beispiel #14
0
func (h *Handler) handleVerifyPost(w http.ResponseWriter, r *http.Request) {
	err := session.SendVerify()
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	flashdata.Set(w, "Verification link sent to your email address")

	http.Redirect(w, r, config.Get("baseurl"), http.StatusFound)
}
Beispiel #15
0
func (h *Handler) handlePull(w http.ResponseWriter, r *http.Request) {
	v, err := invoice.Load(config.Get("invoice_data"))
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	m := new(invoice.Migrate)
	m.Invoice = v

	match, err := filepath.Glob(
		filepath.Join(config.Get("archive_path"), "?*.???*"))
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	m.Archive = make([]*invoice.MigrateArchive, len(match))

	for i, f := range match {
		f = filepath.Base(f)
		m.Archive[i] = &invoice.MigrateArchive{
			f,
			fmt.Sprintf("%s%s/%s", config.Get("baseurl"),
				config.Get("archive_baseurl"), f)}
	}

	b, err := json.MarshalIndent(m, "", "    ")
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	w.Header().Add("Content-Type", "text/plain")
	w.Write(b)
}
Beispiel #16
0
func (h *Handler) handleVerify(w http.ResponseWriter, r *http.Request) {
	segments := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
	vkey := segments[2]

	s, err := session.Verify(vkey)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	s.Save(w, true)

	http.Redirect(w, r, config.Get("baseurl"), http.StatusFound)
}
Beispiel #17
0
func Exec(q string, params []interface{}) (sql.Result, error) {
	db, err := sql.Open("sqlite3", config.Get("dbf"))
	if err != nil {
		return nil, err
	}
	defer db.Close()

	stmt, err := db.Prepare(q)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	return stmt.Exec(params...)
}
Beispiel #18
0
func Get(w http.ResponseWriter, r *http.Request) (string, bool) {
	c, err := r.Cookie(fmt.Sprintf("%s-flash",
		config.Get("session_cookie_name")))
	if err != nil {
		return "", false
	}

	b, err := base64.URLEncoding.DecodeString(c.Value)
	if err != nil {
		return "", false
	}

	Set(w, "")

	return string(b), true
}
Beispiel #19
0
func SendVerify() error {
	vkey, err := uuid4.New()
	if err != nil {
		return err
	}

	q := `
        INSERT INTO user_verify VALUES(
            NULL
            , ?
            , ?
            , ?
            , ?
        );
    `

	params := []interface{}{
		vkey,
		time.Now().Unix() + VERIFY_OFFSET,
		time.Now().Unix(),
		time.Now().Unix(),
	}

	_, err = dao.Exec(q, params)
	if err != nil {
		return err
	}

	url := fmt.Sprintf("%s/verify/%s", config.Get("baseurl"), vkey)

	loadTemplates()

	tpl := "verify"
	subject := "Please verify your High Tech account"

	html := new(bytes.Buffer)
	Templates.ExecuteTemplate(html, fmt.Sprintf("%s.html", tpl), url)

	text := new(bytes.Buffer)
	Templates.ExecuteTemplate(text, fmt.Sprintf("%s.txt", tpl), url)

	m := awsses.New(
		config.Get("awsses_sender"),
		config.Get("verify_email"),
		subject,
		html.String(),
		text.String())

	return m.Send(
		config.Get("awsses_baseurl"),
		config.Get("awsses_accesskey"),
		config.Get("awsses_secretkey"))
}
Beispiel #20
0
func getData() (*invoice.Migrate, error) {
	url := config.Get("archive_migrate_url")

	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	m := new(invoice.Migrate)
	err = json.Unmarshal(b, m)
	if err != nil {
		return nil, err
	}

	return m, nil
}
Beispiel #21
0
func main() {
	switch len(os.Args) {
	case 1:
		break
	case 2:
		err := os.Chdir(os.Args[1])
		if err != nil {
			panic(err)
		}
		break
	default:
		return
	}

	err := config.Load("./data/data.db")
	if err != nil {
		panic(err)
	}

	config.Dump(os.Stdout)

	h, err := handler.New()
	if err != nil {
		panic(err)
	}

	err = ioutil.WriteFile("./pid", []byte(strconv.Itoa(os.Getpid())), 0644)
	if err != nil {
		panic(err)
	}

	http.Handle("/", h)
	err = http.ListenAndServe(config.Get("bind"), nil)
	if err != nil {
		panic(err)
	}
}
Beispiel #22
0
func (h *Handler) handleClose(w http.ResponseWriter, r *http.Request) {
	_, err := session.Parse(r)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	path := config.Get("invoice_data")
	v, err := invoice.Load(path)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	// HTML
	htmlName := fmt.Sprintf("%s-%s.html", v.User.Prefix,
		v.Invoice.Entries[v.Invoice.EndDate].Key)
	htmlPath := filepath.Join(config.Get("archive_path"), htmlName)

	var htmlBuf bytes.Buffer
	err = h.Templates.ExecuteTemplate(&htmlBuf, "invoice.html", v)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	err = ioutil.WriteFile(htmlPath, htmlBuf.Bytes(), 0644)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	// JSON
	jsonName := fmt.Sprintf("%s-%s.txt", v.User.Prefix,
		v.Invoice.Entries[v.Invoice.EndDate].Key)
	jsonPath := filepath.Join(config.Get("archive_path"), jsonName)

	jsonBytes, err := json.MarshalIndent(v, "", "    ")
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	err = ioutil.WriteFile(jsonPath, jsonBytes, 0644)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	// EMAIL
	m := awsses.New(
		config.Get("awsses_sender"),
		config.Get("awsses_sender"),
		fmt.Sprintf(
			"High Tech Timesheet %s/%s/%d",
			v.Invoice.Entries[v.Invoice.EndDate].MM,
			v.Invoice.Entries[v.Invoice.EndDate].DD,
			v.Invoice.Entries[v.Invoice.EndDate].YYYY),
		"",
		fmt.Sprintf("%d Hours", v.Invoice.Total),
		&awsses.MessageAttachment{htmlBuf.Bytes(), "text/html", htmlName},
		&awsses.MessageAttachment{jsonBytes, "text/plain", jsonName})

	err = m.Send(
		config.Get("awsses_baseurl"),
		config.Get("awsses_accesskey"),
		config.Get("awsses_secretkey"))
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	v2, err := invoice.New(v.Invoice.Entries[v.Invoice.EndDate].Key, time.Hour*24)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	v2.User = v.User
	v2.User.LastInvoice = fmt.Sprintf("%s/%s",
		config.Get("archive_baseurl"), htmlName)

	err = v2.Save(path)
	if err != nil {
		logger.Error(w, err)
		h.serveServerError(w, r)
		return
	}

	http.Redirect(w, r, config.Get("baseurl"), http.StatusFound)
}