mirror of
https://github.com/PeernetOfficial/Cmd.git
synced 2026-07-17 02:47:52 +01:00
New API functions /profile/list, /profile/read, /profile/write
This commit is contained in:
93
API.go
93
API.go
@@ -44,6 +44,9 @@ func startAPI() {
|
||||
router.HandleFunc("/blockchain/self/read", apiBlockchainSelfRead).Methods("GET")
|
||||
router.HandleFunc("/blockchain/self/add/file", apiBlockchainSelfAddFile).Methods("POST")
|
||||
router.HandleFunc("/blockchain/self/list/file", apiBlockchainSelfListFile).Methods("GET")
|
||||
router.HandleFunc("/profile/list", apiProfileList).Methods("GET")
|
||||
router.HandleFunc("/profile/read", apiProfileRead).Methods("GET")
|
||||
router.HandleFunc("/profile/write", apiProfileWrite).Methods("POST")
|
||||
|
||||
for _, listen := range config.APIListen {
|
||||
go startWebServer(listen, config.APIUseSSL, config.APICertificateFile, config.APICertificateKey, router, "API", parseDuration(config.APITimeoutRead), parseDuration(config.APITimeoutWrite))
|
||||
@@ -429,6 +432,96 @@ func apiBlockchainSelfListFile(w http.ResponseWriter, r *http.Request) {
|
||||
apiEncodeJSON(w, r, result)
|
||||
}
|
||||
|
||||
// --- Profile API ---
|
||||
|
||||
// apiProfileData contains profile metadata stored on the blockchain. Any data is treated as untrusted and unverified by default.
|
||||
type apiProfileData struct {
|
||||
Fields []apiBlockRecordProfileField `json:"fields"` // All fields
|
||||
Blobs []apiBlockRecordProfileBlob `json:"blobs"` // All blobs
|
||||
Status int `json:"status"` // Status of the operation, only used when this structure is returned from the API. See core.BlockchainStatusX.
|
||||
}
|
||||
|
||||
/*
|
||||
apiProfileList lists all users profile fields and blobs.
|
||||
|
||||
Request: GET /profile/list
|
||||
Response: 200 with JSON structure apiProfileData
|
||||
*/
|
||||
func apiProfileList(w http.ResponseWriter, r *http.Request) {
|
||||
fields, blobs, status := core.UserProfileList()
|
||||
|
||||
result := apiProfileData{Status: status}
|
||||
for n := range fields {
|
||||
result.Fields = append(result.Fields, apiBlockRecordProfileField{Type: fields[n].Type, Text: fields[n].Text})
|
||||
}
|
||||
for n := range blobs {
|
||||
result.Blobs = append(result.Blobs, apiBlockRecordProfileBlob{Type: blobs[n].Type, Data: blobs[n].Data})
|
||||
}
|
||||
|
||||
apiEncodeJSON(w, r, result)
|
||||
}
|
||||
|
||||
/*
|
||||
apiProfileRead reads a specific users profile field or blob.
|
||||
For the index see core.ProfileFieldX and core.ProfileBlobX constants.
|
||||
|
||||
Request: GET /profile/read?field=[index] or &blob=[index]
|
||||
Response: 200 with JSON structure apiProfileData
|
||||
*/
|
||||
func apiProfileRead(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
fieldN, err1 := strconv.Atoi(r.Form.Get("field"))
|
||||
blobN, err2 := strconv.Atoi(r.Form.Get("blob"))
|
||||
|
||||
if (err1 != nil && err2 != nil) || (err1 == nil && fieldN < 0) || (err2 == nil && blobN < 0) {
|
||||
http.Error(w, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var result apiProfileData
|
||||
|
||||
if err1 == nil {
|
||||
var text string
|
||||
if text, result.Status = core.UserProfileReadField(uint16(fieldN)); result.Status == core.BlockchainStatusOK {
|
||||
result.Fields = append(result.Fields, apiBlockRecordProfileField{Type: uint16(fieldN), Text: text})
|
||||
}
|
||||
} else {
|
||||
var data []byte
|
||||
if data, result.Status = core.UserProfileReadBlob(uint16(blobN)); result.Status == core.BlockchainStatusOK {
|
||||
result.Blobs = append(result.Blobs, apiBlockRecordProfileBlob{Type: uint16(blobN), Data: data})
|
||||
}
|
||||
}
|
||||
|
||||
apiEncodeJSON(w, r, result)
|
||||
}
|
||||
|
||||
/*
|
||||
apiProfileWrite writes a specific users profile field or blob.
|
||||
For the index see core.ProfileFieldX and core.ProfileBlobX constants.
|
||||
|
||||
Request: POST /profile/write with JSON structure apiProfileData
|
||||
Response: 200 with JSON structure apiBlockchainBlockStatus
|
||||
*/
|
||||
func apiProfileWrite(w http.ResponseWriter, r *http.Request) {
|
||||
var input apiProfileData
|
||||
if err := apiDecodeJSON(w, r, &input); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var profile core.BlockRecordProfile
|
||||
|
||||
for n := range input.Fields {
|
||||
profile.Fields = append(profile.Fields, core.BlockRecordProfileField{Type: input.Fields[n].Type, Text: input.Fields[n].Text})
|
||||
}
|
||||
for n := range input.Blobs {
|
||||
profile.Blobs = append(profile.Blobs, core.BlockRecordProfileBlob{Type: input.Blobs[n].Type, Data: input.Blobs[n].Data})
|
||||
}
|
||||
|
||||
newHeight, status := core.UserProfileWrite(profile)
|
||||
|
||||
apiEncodeJSON(w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight})
|
||||
}
|
||||
|
||||
// --- conversion from core to API data ---
|
||||
|
||||
func isFileTagKnownMetadata(tagType uint16) bool {
|
||||
|
||||
119
API.md
119
API.md
@@ -44,6 +44,10 @@ These are the functions provided by the API:
|
||||
/blockchain/self/read Read a block of the blockchain
|
||||
/blockchain/self/add/file Add file to the blockchain
|
||||
/blockchain/self/list/file List all files stored on the blockchain
|
||||
|
||||
/profile/list List all users profile fields and blobs
|
||||
/profile/read Reads a specific users profile field or blob
|
||||
/profile/write Writes a specific users profile field or blob
|
||||
```
|
||||
|
||||
The `/share` functions are providing high-level functionality to work with files. The `/blockchain` functions provide low-level functionality which is typically not needed.
|
||||
@@ -236,7 +240,7 @@ type apiBlockchainBlockStatus struct {
|
||||
}
|
||||
```
|
||||
|
||||
Example POST request data to `http://127.0.0.1:112/blockchain/self/add/file`:
|
||||
Example POST request to `http://127.0.0.1:112/blockchain/self/add/file`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -313,3 +317,116 @@ Example output:
|
||||
"status": 0
|
||||
}
|
||||
```
|
||||
|
||||
## Profile List
|
||||
|
||||
```
|
||||
Request: GET /profile/list
|
||||
|
||||
Response: 200 with JSON structure apiProfileData
|
||||
```
|
||||
|
||||
```go
|
||||
type apiProfileData struct {
|
||||
Fields []apiBlockRecordProfileField `json:"fields"` // All fields
|
||||
Blobs []apiBlockRecordProfileBlob `json:"blobs"` // All blobs
|
||||
Status int `json:"status"` // Status of the operation, only used when this structure is returned from the API. See core.BlockchainStatusX.
|
||||
}
|
||||
|
||||
const (
|
||||
BlockchainStatusOK = 0 // No problems in the blockchain detected.
|
||||
BlockchainStatusBlockNotFound = 1 // Missing block in the blockchain.
|
||||
BlockchainStatusCorruptBlock = 2 // Error block encoding
|
||||
BlockchainStatusCorruptBlockRecord = 3 // Error block record encoding
|
||||
BlockchainStatusDataNotFound = 4 // Requested data not available in the blockchain
|
||||
)
|
||||
```
|
||||
|
||||
Example request: `http://127.0.0.1:112/profile/list`
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"fields": [{
|
||||
"type": 0,
|
||||
"text": "Test Username 2022"
|
||||
}, {
|
||||
"type": 1,
|
||||
"text": "test@example.com"
|
||||
}],
|
||||
"blobs": null,
|
||||
"status": 0
|
||||
}
|
||||
```
|
||||
|
||||
## Profile Read
|
||||
|
||||
This reads a specific users' profile field or blob. For the index see the `ProfileFieldX` and `ProfileBlobX` constants.
|
||||
|
||||
```
|
||||
Request: GET /profile/read?field=[index] or &blob=[index]
|
||||
|
||||
Response: 200 with JSON structure apiProfileData
|
||||
```
|
||||
|
||||
```go
|
||||
// ProfileFieldX constants define well known profile information
|
||||
const (
|
||||
ProfileFieldName = 0 // Arbitrary username
|
||||
ProfileFieldEmail = 1 // Email address
|
||||
ProfileFieldWebsite = 2 // Website address
|
||||
ProfileFieldTwitter = 3 // Twitter account without the @
|
||||
ProfileFieldYouTube = 4 // YouTube channel URL
|
||||
ProfileFieldAddress = 5 // Physical address
|
||||
)
|
||||
|
||||
// ProfileBlobX constants define well known blobs
|
||||
// Pictures should be in JPEG or PNG format.
|
||||
const (
|
||||
ProfileBlobPicture = 0 // Profile picture, unspecified size
|
||||
)
|
||||
```
|
||||
|
||||
Example request to read the users username: `http://127.0.0.1:112/profile/read?field=0`
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"fields": [{
|
||||
"type": 0,
|
||||
"text": "Test Username 2022"
|
||||
}],
|
||||
"blobs": null,
|
||||
"status": 0
|
||||
}
|
||||
```
|
||||
|
||||
## Profile Write
|
||||
|
||||
```
|
||||
Request: POST /profile/write with JSON structure apiProfileData
|
||||
|
||||
Response: 200 with JSON structure apiBlockchainBlockStatus
|
||||
```
|
||||
|
||||
Example POST request to `http://127.0.0.1:112/profile/write`:
|
||||
|
||||
```json
|
||||
{
|
||||
"fields": [{
|
||||
"type": 0,
|
||||
"text": "Test Username 2021"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"height": 1
|
||||
}
|
||||
```
|
||||
|
||||
2
go.mod
2
go.mod
@@ -3,7 +3,7 @@ module github.com/PeernetOfficial/Cmd
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/PeernetOfficial/core v0.0.0-20210828113738-22f21d187a38
|
||||
github.com/PeernetOfficial/core v0.0.0-20210903002426-928c16c492cf
|
||||
github.com/btcsuite/btcd v0.22.0-beta.0.20210625194946-86a17263b0ff
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/mux v1.8.1-0.20200912192056-d07530f46e1e
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,5 +1,5 @@
|
||||
github.com/PeernetOfficial/core v0.0.0-20210828113738-22f21d187a38 h1:WSqqgVAG5pekBrlrj4wpkAfEN/8GgpWDIQQc3/AbCVE=
|
||||
github.com/PeernetOfficial/core v0.0.0-20210828113738-22f21d187a38/go.mod h1:GCG3qjbCPEY+/PGIO76Dj/Dp6JvpMYy0B6T+CbmSk1A=
|
||||
github.com/PeernetOfficial/core v0.0.0-20210903002426-928c16c492cf h1:Hp+32gIAaXZBMPxVmHVY9JhHF9deLmmrnxtruWObP8s=
|
||||
github.com/PeernetOfficial/core v0.0.0-20210903002426-928c16c492cf/go.mod h1:GCG3qjbCPEY+/PGIO76Dj/Dp6JvpMYy0B6T+CbmSk1A=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/akrylysov/pogreb v0.10.1 h1:FqlR8VR7uCbJdfUob916tPM+idpKgeESDXOA1K0DK4w=
|
||||
github.com/akrylysov/pogreb v0.10.1/go.mod h1:pNs6QmpQ1UlTJKDezuRWmaqkgUE2TuU0YTWyqJZ7+lI=
|
||||
|
||||
Reference in New Issue
Block a user