// Delete will remove the entry func (m *DeleteImageTagModel) Delete() (err error) { // check model validity if !m.IsValid() { return errors.New("DeleteImageTagModel is not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } ps1, err := dbase.Prepare(`DELETE tm FROM tagmap AS tm INNER JOIN tags ON tm.tag_id = tags.tag_id WHERE image_id = ? AND tm.tag_id = ? AND ib_id = ?`) if err != nil { return } defer ps1.Close() _, err = ps1.Exec(m.Image, m.Tag, m.Ib) if err != nil { return } return }
// Delete will remove the entry func (m *DeleteTagModel) Delete() (err error) { // check model validity if !m.IsValid() { return errors.New("DeleteTagModel is not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } ps1, err := dbase.Prepare("DELETE FROM tags WHERE tag_id= ? AND ib_id = ? LIMIT 1") if err != nil { return } defer ps1.Close() _, err = ps1.Exec(m.ID, m.Ib) if err != nil { return } return }
// Update will update the entry func (m *UpdateTagModel) Update() (err error) { // check model validity if !m.IsValid() { return errors.New("UpdateTagModel is not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } ps1, err := dbase.Prepare("UPDATE tags SET tag_name= ?, tagtype_id= ? WHERE tag_id = ? AND ib_id = ?") if err != nil { return } defer ps1.Close() _, err = ps1.Exec(m.Tag, m.TagType, m.ID, m.Ib) if err != nil { return } return }
// FromName will get the password and user id from the database for a user name func (u *User) FromName(name string) (err error) { // name cant be empty if len(name) == 0 { return e.ErrUserNotValid } // Get Database handle dbase, err := db.GetDb() if err != nil { return } // get hashed password from database err = dbase.QueryRow("select user_id, user_password from users where user_name = ?", name).Scan(&u.ID, &u.hash) if err != nil { return } u.SetAuthenticated() if !u.IsValid() { return e.ErrUserNotValid } return }
// Delete will remove the entry func (m *DeleteThreadModel) Delete() (err error) { // check model validity if !m.IsValid() { return errors.New("DeleteThreadModel is not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } ps1, err := dbase.Prepare("UPDATE threads SET thread_deleted = ? WHERE thread_id = ? AND ib_id = ?") if err != nil { return } defer ps1.Close() _, err = ps1.Exec(!m.Deleted, m.ID, m.Ib) if err != nil { return } return }
// PruneAnalytics will remove old entries from the analytics table func PruneAnalytics() { // Get Database handle dbase, err := db.GetDb() if err != nil { return } _, err = dbase.Exec("DELETE FROM analytics WHERE request_time < (now() - interval 1 month)") if err != nil { return } return }
// Status will return info func (m *DeleteImageTagModel) Status() (err error) { // Get Database handle dbase, err := db.GetDb() if err != nil { return } // Check if the tag is there err = dbase.QueryRow("SELECT tag_name FROM tags WHERE tag_id = ? AND ib_id = ? LIMIT 1", m.Tag, m.Ib).Scan(&m.Name) if err == sql.ErrNoRows { return e.ErrNotFound } else if err != nil { return } return }
// Status will return info func (m *PurgePostModel) Status() (err error) { // Get Database handle dbase, err := db.GetDb() if err != nil { return } // get thread ib and title err = dbase.QueryRow("SELECT thread_title FROM threads WHERE thread_id = ? AND ib_id = ? LIMIT 1", m.Thread, m.Ib).Scan(&m.Name) if err == sql.ErrNoRows { return e.ErrNotFound } else if err != nil { return } return }
// Status will return info func (m *PurgeThreadModel) Status() (err error) { // Get Database handle dbase, err := db.GetDb() if err != nil { return } // Check if favorite is already there err = dbase.QueryRow("SELECT thread_title FROM threads WHERE thread_id = ? AND ib_id = ? LIMIT 1", m.ID, m.Ib).Scan(&m.Name) if err == sql.ErrNoRows { return e.ErrNotFound } else if err != nil { return } return }
// Submit will insert audit info into the audit log func (m *Audit) Submit() (err error) { if !m.IsValid() { return errors.New("Audit not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } _, err = dbase.Exec("INSERT INTO audit (user_id,ib_id,audit_type,audit_ip,audit_time,audit_action,audit_info) VALUES (?,?,?,?,NOW(),?,?)", m.User, m.Ib, m.Type, m.IP, m.Action, m.Info) if err != nil { return } return }
// IsAuthorized will get the perms and role info from the userid func (u *User) IsAuthorized(ib uint) bool { var err error if !u.IsValid() { return false } // check for invalid stuff if ib == 0 { return false } // Get Database handle dbase, err := db.GetDb() if err != nil { return false } // holds our role var role uint // get data from users table err = dbase.QueryRow(`SELECT COALESCE((SELECT MAX(role_id) FROM user_ib_role_map WHERE user_ib_role_map.user_id = users.user_id AND ib_id = ?),user_role_map.role_id) as role FROM users INNER JOIN user_role_map ON (user_role_map.user_id = users.user_id) WHERE users.user_id = ?`, ib, u.ID).Scan(&role) if err != nil { return false } switch role { case 3: return true case 4: return true default: return false } }
// Password will get the password and name from the database for an instantiated user func (u *User) Password() (err error) { // check user struct validity if !u.IsValid() { return e.ErrUserNotValid } // Get Database handle dbase, err := db.GetDb() if err != nil { return } // get hashed password from database err = dbase.QueryRow("select user_name, user_password from users where user_id = ?", u.ID).Scan(&u.Name, &u.hash) if err != nil { return } return }
// Status will return info func (m *BanIPModel) Status() (err error) { // Get Database handle dbase, err := db.GetDb() if err != nil { return } // get thread ib and title err = dbase.QueryRow(`SELECT post_ip FROM threads INNER JOIN posts ON threads.thread_id = posts.thread_id WHERE ib_id = ? AND threads.thread_id = ? AND post_num = ? LIMIT 1`, m.Ib, m.Thread, m.ID).Scan(&m.IP) if err == sql.ErrNoRows { return e.ErrNotFound } else if err != nil { return } return }
// Status will return info func (m *DeletePostModel) Status() (err error) { // Get Database handle dbase, err := db.GetDb() if err != nil { return } // get thread ib and title err = dbase.QueryRow(`SELECT thread_title, post_deleted FROM threads INNER JOIN posts on threads.thread_id = posts.thread_id WHERE threads.thread_id = ? AND ib_id = ? LIMIT 1`, m.Thread, m.Ib).Scan(&m.Name, &m.Deleted) if err == sql.ErrNoRows { return e.ErrNotFound } else if err != nil { return } return }
// CheckDuplicate will check for duplicate name before registering func CheckDuplicate(name string) (check bool) { // name cant be empty if len(name) == 0 { return true } // Get Database handle dbase, err := db.GetDb() if err != nil { return true } // this will return true if there is a user err = dbase.QueryRow("select count(*) from users where user_name = ?", name).Scan(&check) if err != nil { return true } return }
// Post will add the ip to the table func (m *BanIPModel) Post() (err error) { // check model validity if !m.IsValid() { return errors.New("BanIPModel is not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } _, err = dbase.Exec("INSERT IGNORE INTO banned_ips (user_id,ib_id,ban_ip,ban_reason) VALUES (?,?,?,?)", m.User, m.Ib, m.IP, m.Reason) if err != nil { return } return }
// Status will return info func (m *UpdateTagModel) Status() (err error) { // Get Database handle dbase, err := db.GetDb() if err != nil { return } var dupe bool // check if there is already a tag err = dbase.QueryRow("select count(*) from tags where tag_name = ? AND ib_id = ? AND NOT tag_id = ?", m.Tag, m.Ib, m.ID).Scan(&dupe) if err != nil { return } if dupe { return e.ErrDuplicateTag } return }
// Delete will remove the entry func (m *PurgeThreadModel) Delete() (err error) { // check model validity if !m.IsValid() { return errors.New("PurgeThreadModel is not valid") } // Get Database handle dbase, err := db.GetDb() if err != nil { return } images := []imageInfo{} // Get thread images rows, err := dbase.Query(`SELECT image_id,image_file,image_thumbnail FROM images INNER JOIN posts on images.post_id = posts.post_id INNER JOIN threads on threads.thread_id = posts.thread_id WHERE threads.thread_id = ? AND ib_id = ?`, m.ID, m.Ib) if err != nil { return } defer rows.Close() for rows.Next() { image := imageInfo{} err = rows.Scan(&image.ID, &image.File, &image.Thumb) if err != nil { return err } // Append rows to info struct images = append(images, image) } err = rows.Err() if err != nil { return } // delete thread from database ps1, err := dbase.Prepare("DELETE FROM threads WHERE thread_id= ? AND ib_id = ? LIMIT 1") if err != nil { return } defer ps1.Close() _, err = ps1.Exec(m.ID, m.Ib) if err != nil { return } // delete image files go func() { for _, image := range images { // filename must exist to prevent deleting the directory ;D if image.Thumb == "" { return } if image.File == "" { return } // delete from amazon s3 s3 := amazon.New() s3.Delete(fmt.Sprintf("src/%s", image.File)) if err != nil { return } s3.Delete(fmt.Sprintf("thumb/%s", image.Thumb)) if err != nil { return } os.RemoveAll(filepath.Join(local.Settings.Directories.ImageDir, image.File)) os.RemoveAll(filepath.Join(local.Settings.Directories.ThumbnailDir, image.Thumb)) } }() return }
// Get will gather the information from the database and return it as JSON serialized data func (i *ModLogModel) Get() (err error) { if i.Ib == 0 || i.Page == 0 { return e.ErrNotFound } // Initialize response header response := ModLogType{} // to hold log entries entries := []Log{} // Initialize struct for pagination paged := u.PagedResponse{} // Set current page to parameter paged.CurrentPage = i.Page // Set threads per index page to config setting paged.PerPage = config.Settings.Limits.PostsPerPage // Get Database handle dbase, err := db.GetDb() if err != nil { return } // Get total tag count and put it in pagination struct err = dbase.QueryRow("SELECT count(*) FROM audit WHERE ib_id = ? AND audit_type = 2", i.Ib).Scan(&paged.Total) if err != nil { return } // Calculate Limit and total Pages paged.Get() // Return 404 if page requested is larger than actual pages if i.Page > paged.Pages { return e.ErrNotFound } // get image counts from tagmap rows, err := dbase.Query(`SELECT audit.user_id,user_name, COALESCE((SELECT MAX(role_id) FROM user_ib_role_map WHERE user_ib_role_map.user_id = users.user_id AND ib_id = ?),user_role_map.role_id) as role, audit_time,audit_action,audit_info FROM audit INNER JOIN users ON audit.user_id = users.user_id INNER JOIN user_role_map ON (user_role_map.user_id = users.user_id) WHERE ib_id = ? AND audit_type = 2 ORDER BY audit_id DESC LIMIT ?,?`, i.Ib, i.Ib, paged.Limit, paged.PerPage) if err != nil { return } for rows.Next() { // Initialize posts struct entry := Log{} // Scan rows and place column into struct err := rows.Scan(&entry.UID, &entry.Name, &entry.Group, &entry.Time, &entry.Action, &entry.Meta) if err != nil { return err } // Append rows to info struct entries = append(entries, entry) } if rows.Err() != nil { return } // Add threads slice to items interface paged.Items = entries // Add pagedresponse to the response struct response.Body = paged // This is the data we will serialize i.Result = response return }
// GetDatabaseSettings gets limits that are in the database func GetDatabaseSettings() { // Get Database handle dbase, err := db.GetDb() if err != nil { panic(err) } ps, err := dbase.Prepare("SELECT settings_value FROM settings WHERE settings_key = ? LIMIT 1") if err != nil { panic(err) } defer ps.Close() err = ps.QueryRow("image_minwidth").Scan(&Settings.Limits.ImageMinWidth) if err != nil { panic(err) } err = ps.QueryRow("image_minheight").Scan(&Settings.Limits.ImageMinHeight) if err != nil { panic(err) } err = ps.QueryRow("image_maxwidth").Scan(&Settings.Limits.ImageMaxWidth) if err != nil { panic(err) } err = ps.QueryRow("image_maxheight").Scan(&Settings.Limits.ImageMaxHeight) if err != nil { panic(err) } err = ps.QueryRow("image_maxsize").Scan(&Settings.Limits.ImageMaxSize) if err != nil { panic(err) } err = ps.QueryRow("webm_maxlength").Scan(&Settings.Limits.WebmMaxLength) if err != nil { panic(err) } err = ps.QueryRow("thread_postsmax").Scan(&Settings.Limits.PostsMax) if err != nil { panic(err) } err = ps.QueryRow("comment_maxlength").Scan(&Settings.Limits.CommentMaxLength) if err != nil { panic(err) } err = ps.QueryRow("comment_minlength").Scan(&Settings.Limits.CommentMinLength) if err != nil { panic(err) } err = ps.QueryRow("title_maxlength").Scan(&Settings.Limits.TitleMaxLength) if err != nil { panic(err) } err = ps.QueryRow("title_minlength").Scan(&Settings.Limits.TitleMinLength) if err != nil { panic(err) } err = ps.QueryRow("name_maxlength").Scan(&Settings.Limits.NameMaxLength) if err != nil { panic(err) } err = ps.QueryRow("name_minlength").Scan(&Settings.Limits.NameMinLength) if err != nil { panic(err) } err = ps.QueryRow("tag_maxlength").Scan(&Settings.Limits.TagMaxLength) if err != nil { panic(err) } err = ps.QueryRow("tag_minlength").Scan(&Settings.Limits.TagMinLength) if err != nil { panic(err) } err = ps.QueryRow("thumbnail_maxwidth").Scan(&Settings.Limits.ThumbnailMaxWidth) if err != nil { panic(err) } err = ps.QueryRow("thumbnail_maxheight").Scan(&Settings.Limits.ThumbnailMaxHeight) if err != nil { panic(err) } err = ps.QueryRow("param_maxsize").Scan(&Settings.Limits.ParamMaxSize) if err != nil { panic(err) } err = ps.QueryRow("guest_posting").Scan(&Settings.General.GuestPosting) if err != nil { panic(err) } err = ps.QueryRow("auto_registration").Scan(&Settings.General.AutoRegistration) if err != nil { panic(err) } err = ps.QueryRow("akismet_key").Scan(&Settings.Akismet.Key) if err != nil { panic(err) } err = ps.QueryRow("akismet_host").Scan(&Settings.Akismet.Host) if err != nil { panic(err) } // akismet has been configured if Settings.Akismet.Key != "" { Settings.Akismet.Configured = true } err = ps.QueryRow("sfs_confidence").Scan(&Settings.StopForumSpam.Confidence) if err != nil { panic(err) } err = ps.QueryRow("amazon_region").Scan(&Settings.Amazon.Region) if err != nil { panic(err) } err = ps.QueryRow("amazon_bucket").Scan(&Settings.Amazon.Bucket) if err != nil { panic(err) } err = ps.QueryRow("amazon_id").Scan(&Settings.Amazon.ID) if err != nil { panic(err) } err = ps.QueryRow("amazon_key").Scan(&Settings.Amazon.Key) if err != nil { panic(err) } // amazon has been configured if Settings.Amazon.ID != "" && Settings.Amazon.Key != "" { Settings.Amazon.Configured = true } err = ps.QueryRow("thread_postsperpage").Scan(&Settings.Limits.PostsPerPage) if err != nil { panic(err) } err = ps.QueryRow("index_threadsperpage").Scan(&Settings.Limits.ThreadsPerPage) if err != nil { panic(err) } err = ps.QueryRow("index_postsperthread").Scan(&Settings.Limits.PostsPerThread) if err != nil { panic(err) } err = ps.QueryRow("prim_js").Scan(&Settings.Prim.JS) if err != nil { panic(err) } err = ps.QueryRow("prim_css").Scan(&Settings.Prim.CSS) if err != nil { panic(err) } err = ps.QueryRow("avatar_minwidth").Scan(&Settings.Limits.AvatarMinWidth) if err != nil { panic(err) } err = ps.QueryRow("avatar_minheight").Scan(&Settings.Limits.AvatarMinHeight) if err != nil { panic(err) } err = ps.QueryRow("avatar_maxwidth").Scan(&Settings.Limits.AvatarMaxWidth) if err != nil { panic(err) } err = ps.QueryRow("avatar_maxheight").Scan(&Settings.Limits.AvatarMaxHeight) if err != nil { panic(err) } err = ps.QueryRow("avatar_maxsize").Scan(&Settings.Limits.AvatarMaxSize) if err != nil { panic(err) } err = ps.QueryRow("password_maxlength").Scan(&Settings.Limits.PasswordMaxLength) if err != nil { panic(err) } err = ps.QueryRow("password_minlength").Scan(&Settings.Limits.PasswordMinLength) if err != nil { panic(err) } err = ps.QueryRow("cloudflare_email").Scan(&Settings.CloudFlare.Email) if err != nil { panic(err) } err = ps.QueryRow("cloudflare_key").Scan(&Settings.CloudFlare.Key) if err != nil { panic(err) } // cloudflare has been configured if Settings.CloudFlare.Key != "" { Settings.CloudFlare.Configured = true } return }
// Get will gather the information from the database and return it as JSON serialized data func (m *StatisticsModel) Get() (err error) { // Initialize response header response := StatisticsType{} // holds visitors info visitors := Series{ Name: "Visitors", } // holds count of hits hits := Series{ Name: "Hits", } // Get Database handle dbase, err := db.GetDb() if err != nil { return } // get board stats err = dbase.QueryRow(`SELECT (SELECT COUNT(thread_id) FROM threads WHERE threads.ib_id=imageboards.ib_id AND thread_deleted != 1) AS thread_count, (SELECT COUNT(post_id) FROM threads LEFT JOIN posts ON posts.thread_id = threads.thread_id WHERE threads.ib_id=imageboards.ib_id AND post_deleted != 1) AS post_count, (SELECT COUNT(image_id) FROM threads LEFT JOIN posts ON posts.thread_id = threads.thread_id LEFT JOIN images ON images.post_id = posts.post_id WHERE threads.ib_id=imageboards.ib_id AND post_deleted != 1) AS image_count FROM imageboards WHERE ib_id = ?`, m.Ib).Scan(&response.Threads, &response.Posts, &response.Images) if err != nil { return } // get visitor stats err = dbase.QueryRow(`SELECT COUNT(DISTINCT request_ip) as visitors, COUNT(request_itemkey) as hits FROM analytics WHERE request_time BETWEEN (CURDATE() - INTERVAL 1 DAY) AND now() AND ib_id = ?`, m.Ib).Scan(&response.Visitors, &response.Hits) if err != nil { return } // get visitor period stats for chart ps1, err := dbase.Prepare(`SELECT (now() - interval ? hour) as time, COUNT(DISTINCT request_ip) as visitors, COUNT(request_itemkey) as hits FROM analytics WHERE request_time BETWEEN (now() - interval ? hour) AND (now() - interval ? hour) AND ib_id = ?`) if err != nil { return } defer ps1.Close() // loop through every four hours for hour := 24; hour >= 4; hour-- { if hour%4 == 0 { var label time.Time var visitorCount, hitCount uint // period minus two hours previous := (hour - 4) err := ps1.QueryRow(hour, hour, previous, m.Ib).Scan(&label, &visitorCount, &hitCount) if err != nil { return err } response.Labels = append(response.Labels, label) visitors.Data = append(visitors.Data, visitorCount) hits.Data = append(hits.Data, hitCount) } } response.Series = append(response.Series, visitors, hits) // This is the data we will serialize m.Result = response return }