Ability to add friends. Also, made a few helper functions.

This commit is contained in:
Howl 2016-04-08 19:05:54 +02:00
parent 7b82c98352
commit 44d12d2493
7 changed files with 116 additions and 26 deletions

View File

@ -39,6 +39,10 @@ func Start(conf common.Conf, db *sql.DB) *gin.Engine {
gv1.GET("/friends", Method(v1.FriendsGET, db, common.PrivilegeReadConfidential))
gv1.GET("/friends/with/:id", Method(v1.FriendsWithGET, db, common.PrivilegeReadConfidential))
// Write privilege required
gv1.POST("/friends/add", Method(v1.FriendsAddPOST, db, common.PrivilegeWrite))
gv1.GET("/friends/add/:id", Method(v1.FriendsAddGET, db, common.PrivilegeWrite))
// M E T A
// E T "wow thats so meta"
// T E -- the one who said "wow that's so meta"

View File

@ -22,7 +22,7 @@ func BadgeByIDGET(md common.MethodData) (r common.Response) {
r.Message = "No such badge was found"
return
case err != nil:
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -36,7 +36,7 @@ func BadgesGET(md common.MethodData) (r common.Response) {
var badges []badgeData
rows, err := md.DB.Query("SELECT id, name, icon FROM badges")
if err != nil {
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -45,12 +45,12 @@ func BadgesGET(md common.MethodData) (r common.Response) {
nb := badgeData{}
err = rows.Scan(&nb.ID, &nb.Name, &nb.Icon)
if err != nil {
md.C.Error(err)
md.Err(err)
}
badges = append(badges, nb)
}
if err := rows.Err(); err != nil {
md.C.Error(err)
md.Err(err)
}
r.Code = 200
r.Data = badges

View File

@ -2,6 +2,7 @@ package v1
import (
"database/sql"
"encoding/json"
"strconv"
"strings"
"time"
@ -18,9 +19,9 @@ type friendData struct {
// It retrieves an user's friends, and whether the friendship is mutual or not.
func FriendsGET(md common.MethodData) (r common.Response) {
var myFrienders []int
myFriendersRaw, err := md.DB.Query("SELECT user1 FROM users_relationships WHERE user2 = ?", md.User.UserID)
myFriendersRaw, err := md.DB.Query("SELECT user1 FROM users_relationships WHERE user2 = ?", md.ID())
if err != nil {
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -29,13 +30,13 @@ func FriendsGET(md common.MethodData) (r common.Response) {
var i int
err := myFriendersRaw.Scan(&i)
if err != nil {
md.C.Error(err)
md.Err(err)
continue
}
myFrienders = append(myFrienders, i)
}
if err := myFriendersRaw.Err(); err != nil {
md.C.Error(err)
md.Err(err)
}
// Yes.
@ -53,9 +54,9 @@ ON users_relationships.user2=users_stats.id
WHERE users_relationships.user1=?
ORDER BY users_relationships.id`
results, err := md.DB.Query(myFriendsQuery+common.Paginate(md.C.Query("p"), md.C.Query("l")), md.User.UserID)
results, err := md.DB.Query(myFriendsQuery+common.Paginate(md.C.Query("p"), md.C.Query("l")), md.ID())
if err != nil {
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -74,7 +75,7 @@ ORDER BY users_relationships.id`
myFriends = append(myFriends, newFriend)
}
if err := results.Err(); err != nil {
md.C.Error(err)
md.Err(err)
}
r.Code = 200
@ -91,7 +92,7 @@ func friendPuts(md common.MethodData, row *sql.Rows) (user friendData) {
var showcountry bool
err = row.Scan(&user.ID, &user.Username, &registeredOn, &user.Rank, &latestActivity, &user.UsernameAKA, &badges, &user.Country, &showcountry)
if err != nil {
md.C.Error(err)
md.Err(err)
return
}
@ -112,7 +113,7 @@ func friendPuts(md common.MethodData, row *sql.Rows) (user friendData) {
// If the user wants to stay anonymous, don't show their country.
// This can be overriden if we have the ReadConfidential privilege and the user we are accessing is the token owner.
if !(showcountry || (md.User.Privileges.HasPrivilegeReadConfidential() && user.ID == md.User.UserID)) {
if !(showcountry || (md.User.Privileges.HasPrivilegeReadConfidential() && user.ID == md.ID())) {
user.Country = "XX"
}
return
@ -132,12 +133,87 @@ func FriendsWithGET(md common.MethodData) (r common.Response) {
r.Data = d
return
}
err = md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users_relationships WHERE user1 = ? AND user2 = ? LIMIT 1), EXISTS(SELECT 1 FROM users_relationships WHERE user2 = ? AND user1 = ? LIMIT 1)", md.User.UserID, uid, md.User.UserID, uid).Scan(&d.Friends, &d.Mutual)
err = md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users_relationships WHERE user1 = ? AND user2 = ? LIMIT 1), EXISTS(SELECT 1 FROM users_relationships WHERE user2 = ? AND user1 = ? LIMIT 1)", md.ID(), uid, md.ID(), uid).Scan(&d.Friends, &d.Mutual)
if err != sql.ErrNoRows && err != nil {
md.C.Error(err)
md.Err(err)
r = Err500
return
}
r.Data = d
return
}
// FriendsAddGET is the GET version of FriendsAddPOST.
func FriendsAddGET(md common.MethodData) common.Response {
uidS := md.C.Param("id")
uid, err := strconv.Atoi(uidS)
if err != nil {
return common.Response{
Code: 400,
Message: "Nope. That's not a number.",
}
}
return addFriend(md, uid)
}
type friendAddPOSTData struct {
UserID int `json:"user_id"`
}
// FriendsAddPOST allows for adding friends. Yup. Easy as that.
func FriendsAddPOST(md common.MethodData) (r common.Response) {
d := friendAddPOSTData{}
err := json.Unmarshal(md.RequestData, &d)
if err != nil {
md.Err(err)
r = Err500
return
}
return addFriend(md, d.UserID)
}
func addFriend(md common.MethodData, u int) (r common.Response) {
if md.ID() == u {
r.Code = 400
r.Message = "Just so you know: you can't add yourself to your friends."
return
}
if !userExists(md, u) {
r.Code = 404
r.Message = "I'd also like to be friends with someone who doesn't even exist (???), however that's NOT POSSIBLE."
return
}
var (
relExists bool
isMutual bool
)
err := md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users_relationships WHERE user1 = ? AND user2 = ?), EXISTS(SELECT 1 FROM users_relationships WHERE user2 = ? AND user1 = ?)", md.ID(), u, md.ID(), u).Scan(&relExists, &isMutual)
if err != nil && err != sql.ErrNoRows {
md.Err(err)
r = Err500
return
}
if !relExists {
_, err := md.DB.Exec("INSERT INTO users_relationships(user1, user2) VALUES (?, ?)", md.User.UserID, u)
if err != nil {
md.Err(err)
r = Err500
return
}
}
r.Code = 200
r.Data = friendsWithData{
Friends: relExists,
Mutual: isMutual,
}
return
}
// userExists makes sure an user exists.
func userExists(md common.MethodData, u int) (r bool) {
err := md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users WHERE id = ?)", u).Scan(&r)
if err != nil && err != sql.ErrNoRows {
md.Err(err)
}
return
}

View File

@ -90,13 +90,13 @@ type pingData struct {
// PingGET is a message to check with the API that we are logged in, and know what are our privileges.
func PingGET(md common.MethodData) (r common.Response) {
r.Code = 200
if md.User.UserID == 0 {
if md.ID() == 0 {
r.Message = "You have not given us a token, so we don't know who you are! But you can still login with /api/v1/login " + kaomojis[rn.Intn(len(kaomojis))]
} else {
r.Message = surpriseMe()
}
r.Data = pingData{
ID: md.User.UserID,
ID: md.ID(),
Privileges: int(md.User.Privileges),
}
return

View File

@ -72,7 +72,7 @@ func TokenNewPOST(md common.MethodData) (r common.Response) {
r.Message = "No user with that username/id was found."
return
case err != nil:
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -88,7 +88,7 @@ func TokenNewPOST(md common.MethodData) (r common.Response) {
r.Message = "That password doesn't match!"
return
}
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -116,14 +116,14 @@ func TokenNewPOST(md common.MethodData) (r common.Response) {
break
}
if err != nil {
md.C.Error(err)
md.Err(err)
r = Err500
return
}
}
_, err = md.DB.Exec("INSERT INTO tokens(user, privileges, description, token) VALUES (?, ?, ?, ?)", ret.ID, ret.Privileges, data.Description, tokenMD5)
if err != nil {
md.C.Error(err)
md.Err(err)
r = Err500
return
}

View File

@ -29,7 +29,7 @@ func UserByIDGET(md common.MethodData) (r common.Response) {
var uid int
uidStr := md.C.Param("id")
if uidStr == "self" {
uid = md.User.UserID
uid = md.ID()
} else {
uid, err = strconv.Atoi(uidStr)
if err != nil {
@ -86,7 +86,7 @@ func userPuts(md common.MethodData, row *sql.Row) (r common.Response) {
r.Message = "No such user was found!"
return
case err != nil:
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -122,7 +122,7 @@ func badgesToArray(badges string) []int {
func genCountry(md common.MethodData, uid int, showCountry bool, country string) string {
// If the user wants to stay anonymous, don't show their country.
// This can be overriden if we have the ReadConfidential privilege and the user we are accessing is the token owner.
if showCountry || (md.User.Privileges.HasPrivilegeReadConfidential() && uid == md.User.UserID) {
if showCountry || (md.User.Privileges.HasPrivilegeReadConfidential() && uid == md.ID()) {
return country
}
return "XX"
@ -253,7 +253,7 @@ LIMIT 1
r.Message = "That user could not be found!"
return
case err != nil:
md.C.Error(err)
md.Err(err)
r = Err500
return
}
@ -278,7 +278,7 @@ func UserUserpageGET(md common.MethodData) (r common.Response) {
r.Code = 404
r.Message = "No user with that user ID!"
case err != nil:
md.C.Error(err)
md.Err(err)
r = Err500
return
}

View File

@ -13,3 +13,13 @@ type MethodData struct {
RequestData []byte
C *gin.Context
}
// Err logs an error into gin.
func (md MethodData) Err(err error) {
md.C.Error(err)
}
// ID retrieves the Token's owner user ID.
func (md MethodData) ID() int {
return md.User.UserID
}