예제 #1
0
func adminSupportOpen(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	userId, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		lobster.RedirectMessage(w, r, "/admin/support", L.FormattedError("invalid_user"))
		return
	}
	user := lobster.UserDetails(userId)
	if user == nil {
		lobster.RedirectMessage(w, r, "/admin/support", L.FormattedError("user_not_found"))
		return
	}

	if r.Method == "POST" {
		form := new(AdminSupportOpenForm)
		err := decoder.Decode(form, r.PostForm)
		if err != nil {
			http.Redirect(w, r, fmt.Sprintf("/admin/support/open/%d", userId), 303)
			return
		}

		ticketId, err := ticketOpen(form.UserId, form.Name, form.Message, true)
		if err != nil {
			lobster.RedirectMessage(w, r, fmt.Sprintf("/admin/support/open/%d", userId), L.FormatError(err))
		} else {
			http.Redirect(w, r, fmt.Sprintf("/admin/support/%d", ticketId), 303)
		}
		return
	}

	params := new(AdminSupportOpenParams)
	params.Frame = frameParams
	params.User = user
	params.Token = lobster.CSRFGenerate(session)
	lobster.RenderTemplate(w, "admin", "support_open", params)
}
예제 #2
0
func adminSupportTicketClose(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	ticketId, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		lobster.RedirectMessage(w, r, "/admin/support", L.FormattedError("invalid_ticket"))
		return
	}
	ticketClose(session.UserId, ticketId)
	lobster.LogAction(session.UserId, lobster.ExtractIP(r.RemoteAddr), "Close ticket", fmt.Sprintf("Ticket ID: %d", ticketId))
	lobster.RedirectMessage(w, r, fmt.Sprintf("/admin/support/%d", ticketId), L.Success("ticket_closed"))
}
예제 #3
0
파일: whmcs.go 프로젝트: nhocconan/lobster
func (this *WHMCS) handleToken(w http.ResponseWriter, r *http.Request, db *lobster.Database, session *lobster.Session) {
	if session.IsLoggedIn() {
		lobster.RedirectMessage(w, r, "/panel/dashboard", lobster.L.Info("already_logged_in"))
		return
	}

	r.ParseForm()
	token := r.Form.Get("token")
	if len(token) != TOKEN_LENGTH {
		http.Error(w, "bad token", 403)
	}
	rows := db.Query("SELECT id, user_id FROM whmcs_tokens WHERE token = ? AND time > DATE_SUB(NOW(), INTERVAL 1 MINUTE)", token)
	if !rows.Next() {
		http.Error(w, "invalid token", 403)
	}
	var rowId, userId int
	rows.Scan(&rowId, &userId)
	rows.Close()
	db.Exec("DELETE FROM whmcs_tokens WHERE id = ?", rowId)
	session.UserId = userId // we do not grant admin privileges on the session for WHMCS login
	log.Printf("Authentication via WHMCS for user_id=%d (%s)", userId, r.RemoteAddr)
	lobster.LogAction(db, userId, lobster.ExtractIP(r.RemoteAddr), "Logged in via WHMCS", "")
	http.Redirect(w, r, "/panel/dashboard", 303)

}
예제 #4
0
func panelSupportOpen(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	if r.Method == "POST" {
		form := new(SupportOpenForm)
		err := decoder.Decode(form, r.PostForm)
		if err != nil {
			http.Redirect(w, r, "/panel/support/open", 303)
			return
		}

		ticketId, err := ticketOpen(session.UserId, form.Name, form.Message, false)
		if err != nil {
			lobster.RedirectMessage(w, r, "/panel/support/open", L.FormatError(err))
		} else {
			lobster.LogAction(session.UserId, lobster.ExtractIP(r.RemoteAddr), "Open ticket", fmt.Sprintf("Subject: %s; Ticket ID: %d", form.Name, ticketId))
			http.Redirect(w, r, fmt.Sprintf("/panel/support/%d", ticketId), 303)
		}
		return
	}

	lobster.RenderTemplate(
		w,
		"panel",
		"support_open",
		lobster.PanelFormParams{Frame: frameParams, Token: lobster.CSRFGenerate(session)},
	)
}
예제 #5
0
func adminSupportTicket(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	ticketId, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		lobster.RedirectMessage(w, r, "/admin/support", L.FormattedError("invalid_ticket"))
		return
	}
	ticket := TicketDetails(session.UserId, ticketId, true)
	if ticket == nil {
		lobster.RedirectMessage(w, r, "/admin/support", L.FormattedError("ticket_not_found"))
		return
	}

	params := AdminSupportTicketParams{}
	params.Frame = frameParams
	params.Ticket = ticket
	params.Token = lobster.CSRFGenerate(session)
	lobster.RenderTemplate(w, "admin", "support_ticket", params)
}
예제 #6
0
func adminSupportTicketReply(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	ticketId, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		lobster.RedirectMessage(w, r, "/admin/support", L.FormattedError("invalid_ticket"))
		return
	}
	form := new(AdminSupportTicketReplyForm)
	err = decoder.Decode(form, r.PostForm)
	if err != nil {
		http.Redirect(w, r, fmt.Sprintf("/admin/support/%d", ticketId), 303)
		return
	}

	err = ticketReply(session.UserId, ticketId, form.Message, true)
	if err != nil {
		lobster.RedirectMessage(w, r, fmt.Sprintf("/admin/support/%d", ticketId), L.FormatError(err))
	} else {
		http.Redirect(w, r, fmt.Sprintf("/admin/support/%d", ticketId), 303)
	}
}
예제 #7
0
func panelSupportTicketReply(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	ticketId, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		lobster.RedirectMessage(w, r, "/panel/support", L.FormattedError("invalid_ticket"))
		return
	}
	form := new(SupportTicketReplyForm)
	err = decoder.Decode(form, r.PostForm)
	if err != nil {
		http.Redirect(w, r, fmt.Sprintf("/panel/support/%d", ticketId), 303)
		return
	}

	err = ticketReply(session.UserId, ticketId, form.Message, false)
	if err != nil {
		lobster.RedirectMessage(w, r, fmt.Sprintf("/panel/support/%d", ticketId), L.FormatError(err))
	} else {
		lobster.LogAction(session.UserId, lobster.ExtractIP(r.RemoteAddr), "Ticket reply", fmt.Sprintf("Ticket ID: %d", ticketId))
		http.Redirect(w, r, fmt.Sprintf("/panel/support/%d", ticketId), 303)
	}
}
예제 #8
0
func (sp *StripePayment) handle(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	if !lobster.AntifloodCheck(lobster.ExtractIP(r.RemoteAddr), "payment_stripe_handle", 5) {
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormattedError("try_again_later"))
		return
	}
	lobster.AntifloodAction(lobster.ExtractIP(r.RemoteAddr), "payment_stripe_handle")

	stripeToken := r.PostFormValue("stripeToken")
	amount, amountErr := strconv.Atoi(r.PostFormValue("amount"))
	currency := r.PostFormValue("currency")

	if stripeToken == "" || amount <= 0 || amountErr != nil || currency == "" {
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormatError(fmt.Errorf("credit card payment failed due to form submission error")))
		return
	}

	// duplicate amount range check here since user might tamper with the amount in the form
	cfg := lobster.GetConfig()
	if amount < int(cfg.Billing.DepositMinimum*100) || amount > int(cfg.Billing.DepositMaximum*100) {
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormattedErrorf("amount_between", cfg.Billing.DepositMinimum, cfg.Billing.DepositMaximum))
		return
	}

	chargeParams := &stripe.ChargeParams{
		Amount:   uint64(amount),
		Currency: stripe.Currency(currency),
		Source:   &stripe.SourceParams{Token: stripeToken},
		Desc:     "Lobster credit",
	}
	charge, err := sp.client.Charges.New(chargeParams)

	if err != nil {
		emailParams := StripeErrorEmail{
			fmt.Sprintf("error creating charge for user %d", session.UserId),
			err,
		}
		lobster.MailWrap(-1, "stripeError", emailParams, false)
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormatError(fmt.Errorf("credit card payment error; make sure that you have entered your credit card details correctly")))
		return
	} else if !charge.Paid {
		emailParams := StripeErrorEmail{
			fmt.Sprintf("created charge for user %d but paid is false", session.UserId),
			nil,
		}
		lobster.MailWrap(-1, "stripeError", emailParams, false)
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormatError(fmt.Errorf("credit card payment error; make sure that you have entered your credit card details correctly")))
		return
	}

	transaction := charge.Tx
	lobster.TransactionAdd(
		session.UserId,
		"stripe",
		charge.ID,
		"Stripe payment: "+charge.ID,
		int64(charge.Amount)*lobster.BILLING_PRECISION/100,
		transaction.Fee*lobster.BILLING_PRECISION/100,
	)
	lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.Success("payment_made"))
}
예제 #9
0
func (this *CoinbasePayment) Payment(w http.ResponseWriter, r *http.Request, frameParams lobster.FrameParams, userId int, username string, amount float64) {
	cfg := lobster.GetConfig()
	if cfg.Default.Debug {
		log.Printf("Creating Coinbase button for %s (id=%d) with amount $%.2f", username, userId, amount)
	}
	params := &coinbase.Button{
		Name:             lobster.L.T("credit_for_username", username),
		PriceString:      fmt.Sprintf("%.2f", amount),
		PriceCurrencyIso: cfg.Billing.Currency,
		Custom:           fmt.Sprintf("lobster%d", userId),
		Description:      fmt.Sprintf("Credit %s", lobster.L.T("currency_format", fmt.Sprintf("%.2f", amount))),
		Type:             "buy_now",
		Style:            "buy_now_large",
		CallbackUrl:      cfg.Default.UrlBase + "/coinbase_callback_" + this.callbackSecret,
	}
	cli := coinbase.ApiKeyClient(this.apiKey, this.apiSecret)
	button, err := cli.CreateButton(params)
	if err != nil {
		lobster.ReportError(err, "failed to create Coinbase button", fmt.Sprintf("username=%s, amount=%.2f", username, amount))
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormattedError("try_again_later"))
		return
	}
	http.Redirect(w, r, "https://coinbase.com/checkouts/"+button.Code, 303)
}
예제 #10
0
파일: fake.go 프로젝트: carriercomm/lobster
func (this *FakePayment) Payment(w http.ResponseWriter, r *http.Request, frameParams lobster.FrameParams, userId int, username string, amount float64) {
	lobster.TransactionAdd(userId, "fake", utils.Uid(16), "Fake credit", int64(amount*100)*lobster.BILLING_PRECISION/100, 0)
	lobster.RedirectMessage(w, r, "/panel/billing", lobster.LA("payment_fake").Success("credit_added"))
}