f0e69f78da
* Add an Admin Certification Photo workflow where we can request the user to upload a secondary form of ID (government issued photo ID showing their face and date of birth). * An admin rejection option can request secondary photo ID. * It sends a distinct e-mail to the user apart from the regular rejection email * It flags their cert photo as "Secondary Needed" forever: even if the user removes their cert photo and starts from scratch, it will immediately request secondary ID when uploading a new primary photo. * Secondary photos are deleted from the server on both Approve and Reject by the admin account, for user privacy. * If approved, a Secondary Approved=true boolean is stored in the database. This boolean is set to False if the user deletes their cert photo in the future.
91 lines
2.6 KiB
Go
91 lines
2.6 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// CertificationPhoto table.
|
|
type CertificationPhoto struct {
|
|
ID uint64 `gorm:"primaryKey"`
|
|
UserID uint64 `gorm:"uniqueIndex"`
|
|
Filename string
|
|
Filesize int64
|
|
Status CertificationPhotoStatus
|
|
AdminComment string
|
|
SecondaryNeeded bool // a secondary form of ID has been requested
|
|
SecondaryFilename string // photo ID upload
|
|
SecondaryVerified bool // mark true when ID checked so original can be deleted
|
|
IPAddress string // the IP they uploaded the photo from
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
type CertificationPhotoStatus string
|
|
|
|
const (
|
|
CertificationPhotoNeeded CertificationPhotoStatus = "needed"
|
|
CertificationPhotoPending CertificationPhotoStatus = "pending"
|
|
CertificationPhotoApproved CertificationPhotoStatus = "approved"
|
|
CertificationPhotoRejected CertificationPhotoStatus = "rejected"
|
|
|
|
// If a photo is pending approval but the admin wants to engage the
|
|
// secondary check (prompt user for a photo ID upload)
|
|
CertificationPhotoSecondary CertificationPhotoStatus = "secondary"
|
|
)
|
|
|
|
// GetCertificationPhoto retrieves the user's record from the DB or upserts their initial record.
|
|
func GetCertificationPhoto(userID uint64) (*CertificationPhoto, error) {
|
|
p := &CertificationPhoto{}
|
|
result := DB.Where("user_id = ?", userID).First(&p)
|
|
if result.Error == gorm.ErrRecordNotFound {
|
|
p = &CertificationPhoto{
|
|
UserID: userID,
|
|
Status: CertificationPhotoNeeded,
|
|
}
|
|
result = DB.Create(p)
|
|
return p, result.Error
|
|
}
|
|
return p, result.Error
|
|
}
|
|
|
|
// CertificationPhotosNeedingApproval returns a pager of the pictures that require admin approval.
|
|
func CertificationPhotosNeedingApproval(status CertificationPhotoStatus, pager *Pagination) ([]*CertificationPhoto, error) {
|
|
var p = []*CertificationPhoto{}
|
|
|
|
query := DB.Where(
|
|
"status = ?",
|
|
status,
|
|
).Order(
|
|
pager.Sort,
|
|
)
|
|
|
|
// Get the total count.
|
|
query.Model(&CertificationPhoto{}).Count(&pager.Total)
|
|
|
|
result := query.Offset(
|
|
pager.GetOffset(),
|
|
).Limit(pager.PerPage).Find(&p)
|
|
|
|
return p, result.Error
|
|
}
|
|
|
|
// CountCertificationPhotosNeedingApproval gets the count of pending photos for admin alert.
|
|
func CountCertificationPhotosNeedingApproval() int64 {
|
|
var count int64
|
|
DB.Where("status = ?", CertificationPhotoPending).Model(&CertificationPhoto{}).Count(&count)
|
|
return count
|
|
}
|
|
|
|
// Save photo.
|
|
func (p *CertificationPhoto) Save() error {
|
|
result := DB.Save(p)
|
|
return result.Error
|
|
}
|
|
|
|
// Delete the DB entry.
|
|
func (p *CertificationPhoto) Delete() error {
|
|
return DB.Delete(p).Error
|
|
}
|