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) }
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")) }
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) }
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)}, ) }
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) }
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) } }
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) } }
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")) }
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) }
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")) }