ref: main
./kosyncsrv.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
package main import ( "flag" "fmt" "net/http" "github.com/gin-gonic/gin" _ "github.com/mattn/go-sqlite3" ) type requestUser struct { Username string `json:"username"` Password string `json:"password"` } type requestHeader struct { AuthUser string `header:"x-auth-user"` AuthKey string `header:"x-auth-key"` } type requestPosition struct { DocumentID string `json:"document"` Percentage float64 `json:"percentage"` Progress string `json:"progress"` Device string `json:"device"` DeviceID string `json:"device_id"` } type replayPosition struct { DocumentID string Timestamp int64 } type requestDocid struct { DocumentID string `uri:"document" bingding:"required"` } func register(c *gin.Context) { var rUser requestUser if err := c.ShouldBindJSON(&rUser); err != nil { c.String(http.StatusBadRequest, "Bind Json error") return } if rUser.Username == "" || rUser.Password == "" { c.String(http.StatusBadRequest, "Invalid request") return } else if !addDBUser(rUser.Username, rUser.Password) { c.String(http.StatusConflict, "Username is already registered") return } else { c.JSON(http.StatusCreated, gin.H{ "username": rUser.Username, }) return } } func authorizeRequest(c *gin.Context) (ruser string) { var rHeader requestHeader if err := c.ShouldBindHeader(&rHeader); err != nil { c.String(http.StatusBadRequest, "Bind Header error") } if rHeader.AuthUser == "" || rHeader.AuthKey == "" { c.String(http.StatusUnauthorized, "Wrong header or Blank Value") return ruser } dUser, norows := getDBUser(rHeader.AuthUser) if norows { c.String(http.StatusForbidden, "Forbidden") return ruser } else if rHeader.AuthKey != dUser.Password { c.String(http.StatusUnauthorized, "Unauthorized") return ruser } else { return rHeader.AuthUser } } func authorize(c *gin.Context) { _ = authorizeRequest(c) c.JSON(200, gin.H{ "authorized": "OK", }) } func getProgress(c *gin.Context) { ruser := authorizeRequest(c) var rDocid requestDocid if err := c.ShouldBindUri(&rDocid); err != nil { c.JSON(http.StatusBadRequest, gin.H{"msg": err}) return } position := getDBPosition(ruser, rDocid.DocumentID) c.JSON(http.StatusOK, position) } func updateProgress(c *gin.Context) { ruser := authorizeRequest(c) var rPosition requestPosition var reply replayPosition if err := c.ShouldBindJSON(&rPosition); err != nil { c.String(http.StatusBadRequest, "Bind Json error") return } updatetime := updateDBdocument(ruser, rPosition) reply.DocumentID = rPosition.DocumentID reply.Timestamp = updatetime c.JSON(http.StatusOK, reply) } func main() { dbfile := flag.String("d", "syncdata.db", "Sqlite3 DB file name") dbname = *dbfile srvhost := flag.String("t", "127.0.0.1", "Server host") srvport := flag.Int("p", 8080, "Server port") sslswitch := flag.Bool("ssl", false, "Start with https") sslc := flag.String("c", "", "SSL Certificate file") sslk := flag.String("k", "", "SSL Private key file") flag.Usage = func() { fmt.Println(`Usage: kosyncsrv [-h] [-t 127.0.0.1] [-p 8080] [-ssl -c "./cert.pem" -k "./cert.key"]`) flag.PrintDefaults() } flag.Parse() bindsrv := *srvhost + ":" + fmt.Sprint(*srvport) initDB() router := gin.Default() router.POST("/users/create", register) router.GET("/users/auth", authorize) router.GET("/syncs/progress/:document", getProgress) router.PUT("/syncs/progress", updateProgress) if *sslswitch { router.RunTLS(bindsrv, *sslc, *sslk) } else { router.Run(bindsrv) } } |