2016-04-03 17:59:27 +00:00
|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
2016-06-16 10:45:10 +00:00
|
|
|
"fmt"
|
2018-01-21 20:21:46 +00:00
|
|
|
"time"
|
2016-04-03 17:59:27 +00:00
|
|
|
|
2016-10-02 17:47:31 +00:00
|
|
|
"github.com/DataDog/datadog-go/statsd"
|
2017-02-02 12:40:28 +00:00
|
|
|
fhr "github.com/buaazp/fasthttprouter"
|
2016-06-16 10:45:10 +00:00
|
|
|
"github.com/getsentry/raven-go"
|
2016-08-15 11:37:03 +00:00
|
|
|
"github.com/jmoiron/sqlx"
|
2016-11-19 18:53:55 +00:00
|
|
|
"gopkg.in/redis.v5"
|
2019-02-25 21:04:55 +00:00
|
|
|
"github.com/osuyozora/api/app/internals"
|
|
|
|
"github.com/osuyozora/api/app/peppy"
|
|
|
|
"github.com/osuyozora/api/app/v1"
|
|
|
|
"github.com/osuyozora/api/app/websockets"
|
|
|
|
"github.com/osuyozora/api/common"
|
2019-02-03 12:49:32 +00:00
|
|
|
)
|
2016-04-03 17:59:27 +00:00
|
|
|
|
2016-08-09 21:06:23 +00:00
|
|
|
var (
|
2016-10-02 17:47:31 +00:00
|
|
|
db *sqlx.DB
|
|
|
|
cf common.Conf
|
|
|
|
doggo *statsd.Client
|
2016-11-19 18:53:55 +00:00
|
|
|
red *redis.Client
|
2016-08-09 21:06:23 +00:00
|
|
|
)
|
2016-05-15 11:57:04 +00:00
|
|
|
|
2016-04-03 17:59:27 +00:00
|
|
|
// Start begins taking HTTP connections.
|
2017-02-02 12:40:28 +00:00
|
|
|
func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
|
2016-05-15 11:57:04 +00:00
|
|
|
db = dbO
|
2016-08-09 21:06:23 +00:00
|
|
|
cf = conf
|
2016-07-06 14:33:58 +00:00
|
|
|
|
2017-02-02 12:53:36 +00:00
|
|
|
rawRouter := fhr.New()
|
|
|
|
r := router{rawRouter}
|
2017-02-02 12:40:28 +00:00
|
|
|
// TODO: add back gzip
|
|
|
|
// TODO: add logging
|
|
|
|
// TODO: add sentry panic recovering
|
2016-06-16 10:45:10 +00:00
|
|
|
|
2016-10-02 17:47:31 +00:00
|
|
|
// sentry
|
2016-06-16 10:45:10 +00:00
|
|
|
if conf.SentryDSN != "" {
|
|
|
|
ravenClient, err := raven.New(conf.SentryDSN)
|
2016-06-17 08:34:53 +00:00
|
|
|
ravenClient.SetRelease(common.Version)
|
2016-06-16 10:45:10 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
} else {
|
2017-02-02 12:40:28 +00:00
|
|
|
// r.Use(Recovery(ravenClient, false))
|
|
|
|
common.RavenClient = ravenClient
|
2016-06-16 10:45:10 +00:00
|
|
|
}
|
|
|
|
}
|
2016-04-03 17:59:27 +00:00
|
|
|
|
2016-10-02 17:47:31 +00:00
|
|
|
// datadog
|
2016-10-02 19:58:43 +00:00
|
|
|
var err error
|
|
|
|
doggo, err = statsd.New("127.0.0.1:8125")
|
2016-10-02 17:47:31 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
|
|
|
doggo.Namespace = "api."
|
|
|
|
|
2016-11-19 18:53:55 +00:00
|
|
|
// redis
|
|
|
|
red = redis.NewClient(&redis.Options{
|
|
|
|
Addr: conf.RedisAddr,
|
|
|
|
Password: conf.RedisPassword,
|
|
|
|
DB: conf.RedisDB,
|
|
|
|
})
|
2017-04-11 21:18:02 +00:00
|
|
|
peppy.R = red
|
2016-11-19 18:53:55 +00:00
|
|
|
|
2016-12-01 22:16:36 +00:00
|
|
|
// token updater
|
|
|
|
go tokenUpdater(db)
|
|
|
|
|
2017-02-19 17:19:59 +00:00
|
|
|
// start websocket
|
|
|
|
websockets.Start(red, db)
|
|
|
|
|
2018-01-21 20:21:46 +00:00
|
|
|
// start load achievements
|
|
|
|
go v1.LoadAchievementsEvery(db, time.Minute*10)
|
|
|
|
|
2017-02-02 12:40:28 +00:00
|
|
|
// peppyapi
|
2016-04-03 17:59:27 +00:00
|
|
|
{
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Peppy("/api/get_user", peppy.GetUser)
|
|
|
|
r.Peppy("/api/get_match", peppy.GetMatch)
|
|
|
|
r.Peppy("/api/get_user_recent", peppy.GetUserRecent)
|
|
|
|
r.Peppy("/api/get_user_best", peppy.GetUserBest)
|
|
|
|
r.Peppy("/api/get_scores", peppy.GetScores)
|
|
|
|
r.Peppy("/api/get_beatmaps", peppy.GetBeatmap)
|
2017-02-02 12:40:28 +00:00
|
|
|
}
|
2016-09-02 16:14:23 +00:00
|
|
|
|
2017-02-02 12:40:28 +00:00
|
|
|
// v1 API
|
|
|
|
{
|
2017-02-02 12:53:36 +00:00
|
|
|
r.POSTMethod("/api/v1/tokens/self/delete", v1.TokenSelfDeletePOST)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
|
|
|
// Auth-free API endpoints (public data)
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Method("/api/v1/ping", v1.PingGET)
|
|
|
|
r.Method("/api/v1/surprise_me", v1.SurpriseMeGET)
|
|
|
|
r.Method("/api/v1/users", v1.UsersGET)
|
|
|
|
r.Method("/api/v1/users/whatid", v1.UserWhatsTheIDGET)
|
|
|
|
r.Method("/api/v1/users/full", v1.UserFullGET)
|
2019-02-24 00:35:04 +00:00
|
|
|
r.Method("/api/v1/users/rx/full", v1.UserFullGETRx)
|
|
|
|
r.Method("/api/v1/users/ap/full", v1.UserFullGETAp)
|
2018-01-21 20:21:46 +00:00
|
|
|
r.Method("/api/v1/users/achievements", v1.UserAchievementsGET)
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Method("/api/v1/users/userpage", v1.UserUserpageGET)
|
|
|
|
r.Method("/api/v1/users/lookup", v1.UserLookupGET)
|
|
|
|
r.Method("/api/v1/users/scores/best", v1.UserScoresBestGET)
|
|
|
|
r.Method("/api/v1/users/scores/recent", v1.UserScoresRecentGET)
|
|
|
|
r.Method("/api/v1/badges", v1.BadgesGET)
|
2017-05-01 16:05:22 +00:00
|
|
|
r.Method("/api/v1/badges/members", v1.BadgeMembersGET)
|
2019-02-24 14:23:54 +00:00
|
|
|
r.Method("/api/v1/clans", v1.ClansGET)
|
|
|
|
r.Method("/api/v1/clans/members", v1.ClanMembersGET)
|
|
|
|
r.Method("/api/v1/clans/stats", v1.TotalClanStatsGET)
|
|
|
|
r.Method("/api/v1/clans/stats/all", v1.AllClanStatsGET)
|
|
|
|
r.Method("/api/v1/clans/getinvite", v1.ClanInviteGET)
|
|
|
|
r.Method("/api/v1/clans/isclan", v1.IsInClanGET)
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Method("/api/v1/beatmaps", v1.BeatmapGET)
|
|
|
|
r.Method("/api/v1/leaderboard", v1.LeaderboardGET)
|
2019-02-23 14:06:24 +00:00
|
|
|
r.Method("/api/v1/relaxboard", v1.LeaderboardRxGET)
|
|
|
|
r.Method("/api/v1/autoboard", v1.LeaderboardApGET)
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Method("/api/v1/tokens", v1.TokenGET)
|
|
|
|
r.Method("/api/v1/users/self", v1.UserSelfGET)
|
|
|
|
r.Method("/api/v1/tokens/self", v1.TokenSelfGET)
|
|
|
|
r.Method("/api/v1/blog/posts", v1.BlogPostsGET)
|
|
|
|
r.Method("/api/v1/scores", v1.ScoresGET)
|
|
|
|
r.Method("/api/v1/beatmaps/rank_requests/status", v1.BeatmapRankRequestsStatusGET)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
2019-02-03 12:44:15 +00:00
|
|
|
// Other leaderboard memes
|
2019-02-03 13:06:43 +00:00
|
|
|
r.Method("/api/v1/users/scores/relax/best", v1.UserScoresBestRelaxGET)
|
|
|
|
r.Method("/api/v1/users/scores/relax/recent", v1.UserScoresRecentRelaxGET)
|
|
|
|
r.Method("/api/v1/users/scores/ap/best", v1.UserScoresBestAPGET)
|
|
|
|
r.Method("/api/v1/users/scores/ap/recent", v1.UserScoresRecentAPGET)
|
2019-02-03 12:44:15 +00:00
|
|
|
|
2017-02-02 12:40:28 +00:00
|
|
|
// ReadConfidential privilege required
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Method("/api/v1/friends", v1.FriendsGET, common.PrivilegeReadConfidential)
|
|
|
|
r.Method("/api/v1/friends/with", v1.FriendsWithGET, common.PrivilegeReadConfidential)
|
|
|
|
r.Method("/api/v1/users/self/donor_info", v1.UsersSelfDonorInfoGET, common.PrivilegeReadConfidential)
|
|
|
|
r.Method("/api/v1/users/self/favourite_mode", v1.UsersSelfFavouriteModeGET, common.PrivilegeReadConfidential)
|
|
|
|
r.Method("/api/v1/users/self/settings", v1.UsersSelfSettingsGET, common.PrivilegeReadConfidential)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
|
|
|
// Write privilege required
|
2017-02-02 12:53:36 +00:00
|
|
|
r.POSTMethod("/api/v1/friends/add", v1.FriendsAddPOST, common.PrivilegeWrite)
|
|
|
|
r.POSTMethod("/api/v1/friends/del", v1.FriendsDelPOST, common.PrivilegeWrite)
|
|
|
|
r.POSTMethod("/api/v1/users/self/settings", v1.UsersSelfSettingsPOST, common.PrivilegeWrite)
|
|
|
|
r.POSTMethod("/api/v1/users/self/userpage", v1.UserSelfUserpagePOST, common.PrivilegeWrite)
|
|
|
|
r.POSTMethod("/api/v1/beatmaps/rank_requests", v1.BeatmapRankRequestsSubmitPOST, common.PrivilegeWrite)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
2017-12-09 08:36:00 +00:00
|
|
|
// Admin: RAP
|
|
|
|
r.POSTMethod("/api/v1/rap/log", v1.RAPLogPOST)
|
|
|
|
|
2017-02-02 12:40:28 +00:00
|
|
|
// Admin: beatmap
|
2017-02-02 12:53:36 +00:00
|
|
|
r.POSTMethod("/api/v1/beatmaps/set_status", v1.BeatmapSetStatusPOST, common.PrivilegeBeatmap)
|
|
|
|
r.Method("/api/v1/beatmaps/ranked_frozen_full", v1.BeatmapRankedFrozenFullGET, common.PrivilegeBeatmap)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
|
|
|
// Admin: user managing
|
2017-02-02 12:53:36 +00:00
|
|
|
r.POSTMethod("/api/v1/users/manage/set_allowed", v1.UserManageSetAllowedPOST, common.PrivilegeManageUser)
|
2017-11-18 15:28:59 +00:00
|
|
|
r.POSTMethod("/api/v1/users/edit", v1.UserEditPOST, common.PrivilegeManageUser)
|
2018-02-25 10:30:11 +00:00
|
|
|
r.POSTMethod("/api/v1/users/wipe", v1.WipeUserPOST, common.PrivilegeManageUser)
|
2018-05-03 20:28:38 +00:00
|
|
|
r.POSTMethod("/api/v1/scores/reports", v1.ScoreReportPOST, common.PrivilegeManageUser)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
|
|
|
// M E T A
|
|
|
|
// E T "wow thats so meta"
|
|
|
|
// T E -- the one who said "wow thats so meta"
|
|
|
|
// A T E M
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Method("/api/v1/meta/restart", v1.MetaRestartGET, common.PrivilegeAPIMeta)
|
|
|
|
r.Method("/api/v1/meta/up_since", v1.MetaUpSinceGET, common.PrivilegeAPIMeta)
|
|
|
|
r.Method("/api/v1/meta/update", v1.MetaUpdateGET, common.PrivilegeAPIMeta)
|
2017-02-02 12:40:28 +00:00
|
|
|
|
|
|
|
// User Managing + meta
|
2017-02-02 12:53:36 +00:00
|
|
|
r.POSTMethod("/api/v1/tokens/fix_privileges", v1.TokenFixPrivilegesPOST,
|
|
|
|
common.PrivilegeManageUser, common.PrivilegeAPIMeta)
|
2017-02-02 12:40:28 +00:00
|
|
|
}
|
2016-04-10 21:14:44 +00:00
|
|
|
|
2017-02-19 17:19:59 +00:00
|
|
|
// Websocket API
|
|
|
|
{
|
|
|
|
r.PlainGET("/api/v1/ws", websockets.WebsocketV1Entry)
|
|
|
|
}
|
|
|
|
|
2017-02-02 12:40:28 +00:00
|
|
|
// in the new osu-web, the old endpoints are also in /v1 it seems. So /shrug
|
|
|
|
{
|
2017-02-02 12:53:36 +00:00
|
|
|
r.Peppy("/api/v1/get_user", peppy.GetUser)
|
|
|
|
r.Peppy("/api/v1/get_match", peppy.GetMatch)
|
|
|
|
r.Peppy("/api/v1/get_user_recent", peppy.GetUserRecent)
|
|
|
|
r.Peppy("/api/v1/get_user_best", peppy.GetUserBest)
|
|
|
|
r.Peppy("/api/v1/get_scores", peppy.GetScores)
|
|
|
|
r.Peppy("/api/v1/get_beatmaps", peppy.GetBeatmap)
|
2016-04-03 17:59:27 +00:00
|
|
|
}
|
|
|
|
|
2017-02-02 12:40:28 +00:00
|
|
|
r.GET("/api/status", internals.Status)
|
|
|
|
|
2017-02-02 12:53:36 +00:00
|
|
|
rawRouter.NotFound = v1.Handle404
|
2016-04-07 17:32:48 +00:00
|
|
|
|
2017-02-02 12:53:36 +00:00
|
|
|
return rawRouter
|
2016-04-03 17:59:27 +00:00
|
|
|
}
|