| package main | |||||
| import ( | |||||
| "biukop.com/sfm/loan" | |||||
| "fmt" | |||||
| "github.com/brianvoe/gofakeit/v6" | |||||
| log "github.com/sirupsen/logrus" | |||||
| "net/http" | |||||
| "net/smtp" | |||||
| "strings" | |||||
| ) | |||||
| func apiV1EmailPassword(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| id := r.URL.Path[len(apiV1Prefix+"email-password/"):] //remove prefix | |||||
| u := loan.User{} | |||||
| e := u.Read(id) | |||||
| if e != nil { | |||||
| apiV1Client403Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| newPass := gofakeit.Password(true, true, true, false, false, 8) | |||||
| log.Info("newPass", u, newPass) | |||||
| u.SetPass(newPass) | |||||
| e = u.Write() | |||||
| if e != nil { | |||||
| apiV1Client403Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| sendEmailPassLink(u, u.Login, newPass) | |||||
| apiV1SendJson(true, w, r, ss) | |||||
| } | |||||
| func sendEmailPassLink(user loan.User, email string, pass string) { | |||||
| // Sender data. | |||||
| from := "mailer@biukop.com.au" | |||||
| password := "hpfitsrujgkewcdw" | |||||
| // Receiver email address. | |||||
| to := []string{ | |||||
| "patrick@biukop.com.au", | |||||
| email, | |||||
| } | |||||
| // smtp server configuration. | |||||
| smtpHost := "smtp.gmail.com" | |||||
| smtpPort := "587" | |||||
| raw := `Subject: Password Reset | |||||
| Dear {user}, | |||||
| We have reset your password to {pass}. Please logon to https://sfmarkets.com.au/broker to check your new credentials. | |||||
| There is no need to reply this mail. If you encounter any difficulties, please contact SuperFinance market directly. | |||||
| This is an automated email, and no one is monitoring this mailbox, please do not reply. | |||||
| Kind Regards | |||||
| Biukop Mailing service team. | |||||
| ` | |||||
| raw = strings.Replace(raw, "{user}", user.Display, -1) | |||||
| raw = strings.Replace(raw, "{pass}", pass, -1) | |||||
| // Message. | |||||
| message := []byte(raw) | |||||
| // Authentication. | |||||
| auth := smtp.PlainAuth("", from, password, smtpHost) | |||||
| // Sending email. | |||||
| err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, message) | |||||
| if err != nil { | |||||
| fmt.Println(err) | |||||
| return | |||||
| } | |||||
| fmt.Println("Email Sent Successfully!") | |||||
| } |
| package main | |||||
| import "testing" | |||||
| func TestSendEmail(t *testing.T) { | |||||
| // sendEmailPassLink("sp@lawipac.com", "somepass") | |||||
| } |
| "github.com/brianvoe/gofakeit/v6" | "github.com/brianvoe/gofakeit/v6" | ||||
| log "github.com/sirupsen/logrus" | log "github.com/sirupsen/logrus" | ||||
| "net/http" | "net/http" | ||||
| "strings" | |||||
| ) | ) | ||||
| func apiV1PeopleList(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | func apiV1PeopleList(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | ||||
| ret := UserExtra{} | ret := UserExtra{} | ||||
| ret.Role = loan.GetRoleById(id) | ret.Role = loan.GetRoleById(id) | ||||
| //TODO; check manager and account role | //TODO; check manager and account role | ||||
| switch ret.Role { | |||||
| switch strings.ToLower(ret.Role) { | |||||
| case "people": | case "people": | ||||
| apiV1SendJson(ret, w, r, ss) | apiV1SendJson(ret, w, r, ss) | ||||
| return | return |
| package main | |||||
| import ( | |||||
| "biukop.com/sfm/loan" | |||||
| "bytes" | |||||
| "database/sql" | |||||
| "encoding/json" | |||||
| log "github.com/sirupsen/logrus" | |||||
| "io" | |||||
| "net/http" | |||||
| "strings" | |||||
| "time" | |||||
| ) | |||||
| func apiV1StepUploadsPost(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| id := r.URL.Path[len(apiV1Prefix+"step-upload/"):] //remove prefix | |||||
| s := loan.Steps{} | |||||
| e := s.Read(id) | |||||
| if e != nil { | |||||
| apiV1Client404Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| if e != nil { | |||||
| log.Error("cannot read step Id for new upload", s, e) | |||||
| apiV1Server500Error(w, r) | |||||
| return | |||||
| } | |||||
| if s.LoanId != s.LoanId { | |||||
| log.Error("loanId mis-match for step upload", s) | |||||
| apiV1Client403Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| s.UploadedAt = time.Now() | |||||
| e = saveStepUploadToDb(&s, r) | |||||
| if e != nil { | |||||
| s.FileContent = s.FileContent[0:512] //only keep first 512 byte for log purpose | |||||
| log.Println("failed to save step uploads", s, e) | |||||
| apiV1Server500Error(w, r) | |||||
| return | |||||
| } | |||||
| s.FileContent = nil | |||||
| apiV1SendJson(s, w, r, ss) | |||||
| } | |||||
| func saveStepUploadToDb(step *loan.Steps, r *http.Request) (e error) { | |||||
| e = r.ParseMultipartForm(10 << 20) | |||||
| if e != nil { | |||||
| return | |||||
| } | |||||
| file, header, e := r.FormFile("files") | |||||
| if e != nil { | |||||
| log.Error("Error Getting StepUpload File", e) | |||||
| return | |||||
| } | |||||
| buf := new(strings.Builder) | |||||
| n, err := io.Copy(buf, file) | |||||
| if err != nil { | |||||
| log.Error("Error copy StepUpload File to memory", e, n) | |||||
| return err | |||||
| } | |||||
| step.FileName = header.Filename | |||||
| step.FileSize = int(header.Size) | |||||
| step.FileMime = header.Header.Get("Content-type") | |||||
| step.FileContent = []byte(buf.String()) | |||||
| e = step.Write() | |||||
| return | |||||
| } | |||||
| func apiV1StepUploadsDownload(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| id := r.URL.Path[len(apiV1Prefix+"step-download/"):] //remove prefix | |||||
| s := loan.Steps{} | |||||
| e := s.ReadWithContent(id) | |||||
| if e != nil { | |||||
| if e != sql.ErrNoRows { | |||||
| log.Warn("invalid upload id", e, id) | |||||
| apiV1Client403Error(w, r, ss) | |||||
| } | |||||
| return | |||||
| } | |||||
| w.Header().Set("Content-Disposition", "attachment; filename="+s.FileName) | |||||
| w.Header().Set("Content-Type", s.FileMime) | |||||
| http.ServeContent(w, r, s.FileName, s.UploadedAt, bytes.NewReader(s.FileContent)) | |||||
| } | |||||
| func decodeJsonStep(r *http.Request) (ret loan.Steps, e error) { | |||||
| decoder := json.NewDecoder(r.Body) | |||||
| //decoder.DisallowUnknownFields() | |||||
| e = decoder.Decode(&ret) | |||||
| if e != nil { | |||||
| log.Error("failed decoding json for Filtering full_loan_summary ", e.Error()) | |||||
| return | |||||
| } | |||||
| return | |||||
| } | |||||
| func apiV1StepUploadsGetID(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| step, e := decodeJsonStep(r) | |||||
| if e != nil || step.StepIndex <= 0 { | |||||
| log.Error("unauthorized parameters for upload step attachment", step) | |||||
| apiV1Client403Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| e = step.GetIdByLoanIdAndIdx(step.LoanId, step.StepIndex) | |||||
| if e != nil { | |||||
| log.Error("cannot get step id for Loan, and index", step, e) | |||||
| apiV1Client404Error(w, r, ss) | |||||
| } else { | |||||
| apiV1SendJson(step, w, r, ss) | |||||
| } | |||||
| } | |||||
| func apiV1StepUploadsMetaPost(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| step, e := decodeJsonStep(r) | |||||
| if e != nil || step.StepIndex <= 0 { | |||||
| log.Error("unauthorized parameters for upload step attachment", step) | |||||
| apiV1Client403Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| e = step.Write() | |||||
| if e != nil { | |||||
| log.Error("cannot get step id for Loan, and index", step, e) | |||||
| apiV1Client404Error(w, r, ss) | |||||
| } else { | |||||
| apiV1SendJson(step, w, r, ss) | |||||
| } | |||||
| } | |||||
| func apiV1StepDelete(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| id := r.URL.Path[len(apiV1Prefix+"step/"):] //remove prefix | |||||
| step := loan.Steps{Id: id} | |||||
| e := step.Read(id) | |||||
| if e != nil { | |||||
| apiV1Client404Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| e = step.Delete() | |||||
| if e != nil { | |||||
| apiV1Server500Error(w, r) | |||||
| } else { | |||||
| apiV1SendJson(true, w, r, ss) | |||||
| } | |||||
| return | |||||
| } | |||||
| func apiV1StepDeleteFile(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| id := r.URL.Path[len(apiV1Prefix+"step-file/"):] //remove prefix | |||||
| step := loan.Steps{Id: id} | |||||
| e := step.Read(id) | |||||
| if e != nil { | |||||
| apiV1Client404Error(w, r, ss) | |||||
| return | |||||
| } | |||||
| e = step.DeleteFile() | |||||
| if e != nil { | |||||
| apiV1Server500Error(w, r) | |||||
| } else { | |||||
| apiV1SendJson(true, w, r, ss) | |||||
| } | |||||
| return | |||||
| } |
| package main | |||||
| import ( | |||||
| "biukop.com/sfm/loan" | |||||
| log "github.com/sirupsen/logrus" | |||||
| "net/http" | |||||
| "strconv" | |||||
| ) | |||||
| func apiV1StepsMetaGet(w http.ResponseWriter, r *http.Request, ss *loan.Session) { | |||||
| id := r.URL.Path[len(apiV1Prefix+"upload-meta/"):] //remove prefix | |||||
| intId, e := strconv.Atoi(id) | |||||
| if e != nil { | |||||
| log.Println("invalid id for upload get", id, e) | |||||
| apiV1Client403Error(w, r, ss) // bad request | |||||
| return | |||||
| } | |||||
| ulmeta := loan.Uploads{} | |||||
| e = ulmeta.Read(int64(intId)) | |||||
| if e != nil { | |||||
| log.Println("upload not found", id, e) | |||||
| apiV1Client404Error(w, r, ss) // bad request | |||||
| return | |||||
| } | |||||
| apiV1SendJson(ulmeta, w, r, ss) | |||||
| } |
| {"POST", "payout-paid/", apiV1PayOutPaid}, | {"POST", "payout-paid/", apiV1PayOutPaid}, | ||||
| {"POST", "payout-unpaid/", apiV1PayOutUnpaid}, | {"POST", "payout-unpaid/", apiV1PayOutUnpaid}, | ||||
| {"POST", "step-upload/", apiV1StepUploadsPost}, | |||||
| {"GET", "step-download/", apiV1StepUploadsDownload}, | |||||
| {"POST", "step-id/", apiV1StepUploadsGetID}, | |||||
| {"POST", "step-meta-update/", apiV1StepUploadsMetaPost}, | |||||
| {"DELETE", "step/", apiV1StepDelete}, | |||||
| {"DELETE", "step-file/", apiV1StepDeleteFile}, | |||||
| {"POST", "email-password/", apiV1EmailPassword}, | |||||
| {"GET", "login", apiV1DumpRequest}, | {"GET", "login", apiV1DumpRequest}, | ||||
| } | } | ||||
| } else { //production | } else { //production | ||||
| {"POST", "payout-paid/", apiV1PayOutPaid}, | {"POST", "payout-paid/", apiV1PayOutPaid}, | ||||
| {"POST", "payout-unpaid/", apiV1PayOutUnpaid}, | {"POST", "payout-unpaid/", apiV1PayOutUnpaid}, | ||||
| {"POST", "step-upload/", apiV1StepUploadsPost}, | |||||
| {"GET", "step-download/", apiV1StepUploadsDownload}, | |||||
| {"POST", "step-id/", apiV1StepUploadsGetID}, | |||||
| {"POST", "step-meta-update/", apiV1StepUploadsMetaPost}, | |||||
| {"DELETE", "step/", apiV1StepDelete}, | |||||
| {"DELETE", "step-file/", apiV1StepDeleteFile}, | |||||
| {"POST", "email-password/", apiV1EmailPassword}, | |||||
| {"GET", "login", apiV1EmptyResponse}, | {"GET", "login", apiV1EmptyResponse}, | ||||
| } | } | ||||
| } | } |
| { | { | ||||
| "Host":"0.0.0.0", | "Host":"0.0.0.0", | ||||
| "Port":"8080", | "Port":"8080", | ||||
| "DSN": "sp:sp@/syd_credit?parseTime=true&loc=Australia%2FSydney", | |||||
| "DSN": "sp:sp@/syd_credit?parseTime=true&loc=Australia%2FSydney&collation=utf8mb4_0900_ai_ci", | |||||
| "TlsCert": "/home/c5016/ssl.combined", | "TlsCert": "/home/c5016/ssl.combined", | ||||
| "TlsKey": "/home/c5016/ssl.key", | "TlsKey": "/home/c5016/ssl.key", | ||||
| "Debug": false, | "Debug": false, |