Remove deprecated API methods
This commit is contained in:
parent
2535a03c5f
commit
6925ce4c6e
|
@ -79,10 +79,6 @@ func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
|
||||||
|
|
||||||
// v1 API
|
// v1 API
|
||||||
{
|
{
|
||||||
// These require an user to pass the password in cleartext and are
|
|
||||||
// as such really insecure.
|
|
||||||
//r.POSTMethod("/api/v1/tokens", v1.TokenNewPOST)
|
|
||||||
//r.POSTMethod("/api/v1/tokens/new", v1.TokenNewPOST)
|
|
||||||
r.POSTMethod("/api/v1/tokens/self/delete", v1.TokenSelfDeletePOST)
|
r.POSTMethod("/api/v1/tokens/self/delete", v1.TokenSelfDeletePOST)
|
||||||
|
|
||||||
// Auth-free API endpoints (public data)
|
// Auth-free API endpoints (public data)
|
||||||
|
@ -132,7 +128,6 @@ func Start(conf common.Conf, dbO *sqlx.DB) *fhr.Router {
|
||||||
// T E -- the one who said "wow thats so meta"
|
// T E -- the one who said "wow thats so meta"
|
||||||
// A T E M
|
// A T E M
|
||||||
r.Method("/api/v1/meta/restart", v1.MetaRestartGET, common.PrivilegeAPIMeta)
|
r.Method("/api/v1/meta/restart", v1.MetaRestartGET, common.PrivilegeAPIMeta)
|
||||||
r.Method("/api/v1/meta/kill", v1.MetaKillGET, common.PrivilegeAPIMeta)
|
|
||||||
r.Method("/api/v1/meta/up_since", v1.MetaUpSinceGET, common.PrivilegeAPIMeta)
|
r.Method("/api/v1/meta/up_since", v1.MetaUpSinceGET, common.PrivilegeAPIMeta)
|
||||||
r.Method("/api/v1/meta/update", v1.MetaUpdateGET, common.PrivilegeAPIMeta)
|
r.Method("/api/v1/meta/update", v1.MetaUpdateGET, common.PrivilegeAPIMeta)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -30,26 +29,6 @@ func MetaRestartGET(md common.MethodData) common.CodeMessager {
|
||||||
return common.SimpleResponse(200, "brb")
|
return common.SimpleResponse(200, "brb")
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetaKillGET kills the API process. NOTE TO EVERYONE: NEVER. EVER. USE IN PROD.
|
|
||||||
// Mainly created because I couldn't bother to fire up a terminal, do htop and kill the API each time.
|
|
||||||
func MetaKillGET(md common.MethodData) common.CodeMessager {
|
|
||||||
proc, err := os.FindProcess(syscall.Getpid())
|
|
||||||
if err != nil {
|
|
||||||
return common.SimpleResponse(500, "couldn't find process. what the fuck?")
|
|
||||||
}
|
|
||||||
const form = "02/01/2006"
|
|
||||||
r := common.ResponseBase{
|
|
||||||
Code: 200,
|
|
||||||
Message: fmt.Sprintf("RIP ripple API %s - %s", upSince.Format(form), time.Now().Format(form)),
|
|
||||||
}
|
|
||||||
// yes
|
|
||||||
go func() {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
proc.Kill()
|
|
||||||
}()
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
var upSince = time.Now()
|
var upSince = time.Now()
|
||||||
|
|
||||||
type metaUpSinceResponse struct {
|
type metaUpSinceResponse struct {
|
||||||
|
|
124
app/v1/token.go
124
app/v1/token.go
|
@ -3,7 +3,6 @@ package v1
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -12,131 +11,10 @@ import (
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
"zxq.co/ripple/rippleapi/common"
|
"zxq.co/ripple/rippleapi/common"
|
||||||
"zxq.co/ripple/rippleapi/limit"
|
|
||||||
"zxq.co/ripple/schiavolib"
|
"zxq.co/ripple/schiavolib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type tokenNewInData struct {
|
|
||||||
// either username or userid must be given in the request.
|
|
||||||
// if none is given, the request is trashed.
|
|
||||||
Username string `json:"username"`
|
|
||||||
UserID int `json:"id"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Privileges int `json:"privileges"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type tokenNewResponse struct {
|
|
||||||
common.ResponseBase
|
|
||||||
Username string `json:"username"`
|
|
||||||
ID int `json:"id"`
|
|
||||||
Privileges int `json:"privileges"`
|
|
||||||
Token string `json:"token,omitempty"`
|
|
||||||
Banned bool `json:"banned"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenNewPOST is the handler for POST /token/new.
|
|
||||||
func TokenNewPOST(md common.MethodData) common.CodeMessager {
|
|
||||||
var r tokenNewResponse
|
|
||||||
data := tokenNewInData{}
|
|
||||||
err := md.Unmarshal(&data)
|
|
||||||
if err != nil {
|
|
||||||
return ErrBadJSON
|
|
||||||
}
|
|
||||||
|
|
||||||
md.Doggo.Incr("tokens.new", nil, 1)
|
|
||||||
|
|
||||||
var miss []string
|
|
||||||
if data.Username == "" && data.UserID == 0 {
|
|
||||||
miss = append(miss, "username|id")
|
|
||||||
}
|
|
||||||
if data.Password == "" {
|
|
||||||
miss = append(miss, "password")
|
|
||||||
}
|
|
||||||
if len(miss) != 0 {
|
|
||||||
return ErrMissingField(miss...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var q *sql.Row
|
|
||||||
const base = "SELECT id, username, privileges, password_md5, password_version, privileges FROM users "
|
|
||||||
if data.UserID != 0 {
|
|
||||||
q = md.DB.QueryRow(base+"WHERE id = ? LIMIT 1", data.UserID)
|
|
||||||
} else {
|
|
||||||
q = md.DB.QueryRow(base+"WHERE username = ? LIMIT 1", common.SafeUsername(data.Username))
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
rank int
|
|
||||||
pw string
|
|
||||||
pwVersion int
|
|
||||||
privilegesRaw uint64
|
|
||||||
)
|
|
||||||
|
|
||||||
err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &privilegesRaw)
|
|
||||||
switch {
|
|
||||||
case err == sql.ErrNoRows:
|
|
||||||
return common.SimpleResponse(404, "No user with that username/id was found.")
|
|
||||||
case err != nil:
|
|
||||||
md.Err(err)
|
|
||||||
return Err500
|
|
||||||
}
|
|
||||||
privileges := common.UserPrivileges(privilegesRaw)
|
|
||||||
|
|
||||||
if !limit.NonBlockingRequest(fmt.Sprintf("loginattempt:%d:%s", r.ID, md.ClientIP()), 5) {
|
|
||||||
return common.SimpleResponse(429, "You've made too many login attempts. Try again later.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pwVersion == 1 {
|
|
||||||
return common.SimpleResponse(418, "That user still has a password in version 1. Unfortunately, in order for the API to check for the password to be OK, the user has to first log in through the website.")
|
|
||||||
}
|
|
||||||
if err := bcrypt.CompareHashAndPassword([]byte(pw), []byte(fmt.Sprintf("%x", md5.Sum([]byte(data.Password))))); err != nil {
|
|
||||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
|
||||||
return common.SimpleResponse(403, "That password doesn't match!")
|
|
||||||
}
|
|
||||||
md.Err(err)
|
|
||||||
return Err500
|
|
||||||
}
|
|
||||||
const want = (common.UserPrivilegePublic | common.UserPrivilegeNormal)
|
|
||||||
if (privileges & want) != want {
|
|
||||||
r.Code = 402
|
|
||||||
r.Message = "That user is banned."
|
|
||||||
r.Banned = true
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
r.Privileges = int(common.Privileges(data.Privileges).CanOnly(privileges))
|
|
||||||
|
|
||||||
var (
|
|
||||||
tokenStr string
|
|
||||||
tokenMD5 string
|
|
||||||
)
|
|
||||||
for {
|
|
||||||
tokenStr = common.RandomString(32)
|
|
||||||
tokenMD5 = fmt.Sprintf("%x", md5.Sum([]byte(tokenStr)))
|
|
||||||
r.Token = tokenStr
|
|
||||||
|
|
||||||
var id int
|
|
||||||
err := md.DB.QueryRow("SELECT id FROM tokens WHERE token=? LIMIT 1", tokenMD5).Scan(&id)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
md.Err(err)
|
|
||||||
return Err500
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = md.DB.Exec("INSERT INTO tokens(user, privileges, description, token, private, last_updated) VALUES (?, ?, ?, ?, '0', ?)",
|
|
||||||
r.ID, r.Privileges, data.Description, tokenMD5, time.Now().Unix())
|
|
||||||
if err != nil {
|
|
||||||
md.Err(err)
|
|
||||||
return Err500
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Code = 200
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenSelfDeletePOST deletes the token the user is connecting with.
|
// TokenSelfDeletePOST deletes the token the user is connecting with.
|
||||||
func TokenSelfDeletePOST(md common.MethodData) common.CodeMessager {
|
func TokenSelfDeletePOST(md common.MethodData) common.CodeMessager {
|
||||||
if md.ID() == 0 {
|
if md.ID() == 0 {
|
||||||
|
@ -177,7 +55,7 @@ func TokenGET(md common.MethodData) common.CodeMessager {
|
||||||
rows, err := md.DB.Query("SELECT id, privileges, description, last_updated FROM tokens "+
|
rows, err := md.DB.Query("SELECT id, privileges, description, last_updated FROM tokens "+
|
||||||
wc.Clause+common.Paginate(md.Query("p"), md.Query("l"), 50), wc.Params...)
|
wc.Clause+common.Paginate(md.Query("p"), md.Query("l"), 50), wc.Params...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Err500
|
return Err500
|
||||||
}
|
}
|
||||||
var r tokenResponse
|
var r tokenResponse
|
||||||
|
|
Loading…
Reference in New Issue
Block a user