Skip to content

Instantly share code, notes, and snippets.

@Savchukv
Last active February 6, 2016 18:24
Show Gist options
  • Save Savchukv/445d3b6c1a4776188947 to your computer and use it in GitHub Desktop.
Save Savchukv/445d3b6c1a4776188947 to your computer and use it in GitHub Desktop.
Server
package main
import (
"database/sql"
"gopkg.in/gorp.v1"
"log"
"net/url"
//"flag"
"strconv"
"time"
"fmt"
"net/http"
"github.com/gorilla/websocket"
"github.com/gin-gonic/gin"
//"golang.org/x/net/websocket"
"github.com/dgrijalva/jwt-go"
_ "github.com/go-sql-driver/mysql"
)
var database *sql.DB
type User struct {
Id int64 `db:"id" json:"id"`
Email string `db:"email" json:"email"`
Username string `db:"username" json:"username"`
Password string `db:"password" json:"password"`
Sex int64 `db:"sex" json:"sex"`
Age int64 `db:"age" json:"age"`
}
type Login struct {
Email string `json: "email" binding: "required"`
Password string `json: "password" binding: "required"`
}
type Check struct {
Email string `json: "email" binding: "required"`
}
var (
validUser = User{Id: 1, Email: "Vas", Username: "Sav"}
mySigningKey = "USEHERE"
)
var dbmap = initDb()
func initDb() *gorp.DbMap {
db, err := sql.Open("mysql", "root:root123456@/myapi")
checkErr(err, "sql.Open failed")
dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
dbmap.AddTableWithName(User{}, "User").SetKeys(true, "Id")
err = dbmap.CreateTablesIfNotExists()
checkErr(err, "Create tables failed")
return dbmap
}
func checkErr(err error, msg string) {
if err != nil {
log.Fatalln(msg, err)
}
}
//var myconn string
//websocket
var connections map[*websocket.Conn]bool
var destinations map[string]*websocket.Conn
func wsHandler(w http.ResponseWriter, r *http.Request) {
// Taken from gorilla's website
conn, err := websocket.Upgrade(w, r, nil, 1024, 1024)
if _, ok := err.(websocket.HandshakeError); ok {
http.Error(w, "Not a websocket handshake", 400)
return
} else if err != nil {
log.Println(err)
return
}
log.Println("Succesfully upgraded connection")
connections[conn] = true
for {
// Blocks until a message is read
_, msg, err := conn.ReadMessage()
if err != nil {
delete(connections, conn)
conn.Close()
return
//log.Println(err)
}
log.Println(string(msg))
sendAll(msg,conn)
}
}
func sendAll(msg []byte, myconn *websocket.Conn) {
for conn := range connections {
if myconn != conn {
if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {
delete(connections, conn)
conn.Close()
}
}
}
}
func wsHandlerChat(w http.ResponseWriter, r *http.Request) {
// Taken from gorilla's website
query := r.URL.Query()
// ws?origin=A&destination=B для юзера A
// ws?origin=B&destination=A для юзера B
originID := query.Get("origin")
destinationID := query.Get("destination")
conn, err := websocket.Upgrade(w, r, nil, 1024, 1024)
if _, ok := err.(websocket.HandshakeError); ok {
http.Error(w, "Not a websocket handshake", 400)
return
} else if err != nil {
log.Println(err)
return
}
destinations[originID] = conn
log.Println("Succesfully upgraded connection")
connections[conn] = true
for {
// Blocks until a message is read
_, msg, err := conn.ReadMessage()
if err != nil {
delete(destinations, originID)
delete(connections, conn)
conn.Close()
return
//log.Println(err)
}
log.Println(string(msg))
connDestination, ok := destinations[destinationID]
if !ok {
log.Println("destination", destinationID, "not found")
continue
}
if err := connDestination.WriteMessage(websocket.TextMessage, msg); err != nil {
delete(connections, connDestination)
delete(destinations, destinationID)
conn.Close()
}
}
}
//end websocket
func main() {
r := gin.Default()
r.GET("/ws", func(c *gin.Context) {
wsHandler(c.Writer, c.Request)
})
r.GET("/ws/chat", func(c *gin.Context) {
wsHandlerChat(c.Writer, c.Request)
})
connections = make(map[*websocket.Conn]bool)
destinations = make(map[string]*websocket.Conn)
v1 := r.Group("api/v1")
{
v1.GET("/users", GetUsers)
v1.GET("/users/:id", GetUser)
v1.GET("/chat/:origin/:destination/:destination/:origin", GetChat)
//v1.GET("/users/email", GetPassword)
v1.POST("/users", PostUser)
v1.PUT("/users/:id", UpdateUser)
v1.DELETE("/users/:id", DeleteUser)
}
r.LoadHTMLGlob("templates/*")
r.GET("/user", func(c *gin.Context) {
c.HTML(http.StatusOK, "user.html", gin.H{
"title": "Main website",
})
})
r.GET("/userget", func(c *gin.Context) {
c.HTML(http.StatusOK, "userget.html", gin.H{
"title": "Main website",
})
})
r.GET("/usergetid", func(c *gin.Context) {
c.HTML(http.StatusOK, "usergetid.html", gin.H{
"title": "Main website",
})
})
r.GET("/deleteuser", func(c *gin.Context) {
c.HTML(http.StatusOK, "deleteuser.html", gin.H{
"title": "Main website",
})
})
r.GET("/updateuser", func(c *gin.Context) {
c.HTML(http.StatusOK, "updateuser.html", gin.H{
"title": "Main website",
})
})
//func to return fogot password
r.Use(func(c *gin.Context) {
// Run this on all requests
// Should be moved to a proper middleware
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Next()
})
r.OPTIONS("/*cors", func(c *gin.Context) {
// Empty 200 response
})
r.POST("/users/token", func(c *gin.Context) {
var login Login
val := c.Bind(&login)
dbb, err:= sql.Open("mysql", "root:root123456@/myapi")
if err != nil {
}
database = dbb
var email string
var password string
sql:= "Select email,password from User where email='" + login.Email + "'"
q:= database.QueryRow(sql).Scan(&email,&password)
if q != nil {
//log.Fatal(q)
}
fmt.Println(email)
fmt.Println(password)
if val!=nil {
c.JSON(200, gin.H{"code": 401, "msg": "Both name & password are required"})
return
}
if login.Email == email && login.Password == password {
// if login.Firstname == dbmap.Select("Select firstname from User where id=1") {
token := jwt.New(jwt.SigningMethodHS256)
// Headers
token.Header["alg"] = "HS256"
token.Header["typ"] = "JWT"
// Claims
token.Claims["name"] = login.Email
token.Claims["mail"] = login.Password
token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
tokenString, err := token.SignedString([]byte(mySigningKey))
if err != nil {
c.JSON(200, gin.H{"code": 500, "msg": "Server error!"})
return
}
c.JSON(200, gin.H{"code": 200, "msg": "OK", "jwt": tokenString})
} else {
c.JSON(200, gin.H{"code": 400, "msg": "Error username or password!"})
}
})
r.POST("/users/balance", func(c *gin.Context) {
token, err := jwt.ParseFromRequest(c.Request, func(token *jwt.Token) (interface{}, error) {
b := ([]byte(mySigningKey))
return b, nil
})
fmt.Println(err)
if err != nil {
c.JSON(200, gin.H{"code": 403, "msg": err.Error()})
} else {
if token.Valid {
token.Claims["balance"] = 49
tokenString, err := token.SignedString([]byte(mySigningKey))
if err != nil {
c.JSON(200, gin.H{"code": 500, "msg": "Server error!"})
return
}
c.JSON(200, gin.H{"code": 200, "msg": "OK", "jwt": tokenString})
} else {
c.JSON(200, gin.H{"code": 401, "msg": "Sorry, you are not validate"})
}
}
})
//check
r.POST("/users/email", func(c *gin.Context) {
var check Check
val := c.Bind(&check)
dbb, err:= sql.Open("mysql", "root:root123456@/myapi")
if err != nil {
}
database = dbb
var email string
var password string
sql:= "Select email,password from User where email='" + check.Email + "'"
q:= database.QueryRow(sql).Scan(&email,&password)
if q != nil {
// log.Fatal(q)
}
fmt.Println(email)
fmt.Println(password)
if val!=nil {
// c.JSON(200, gin.H{"code": 401, "msg": "Both name & password are required"})
//return
}
if check.Email == email {
//if 1==1 {
c.JSON(200, gin.H{"code": 200, "msg": "OK", "Your Password": password})
} else {
c.JSON(200, gin.H{"code": 400, "msg": "Error Mail!"})
}
})
r.Run(":8080")
}
func GetUsers(c *gin.Context) {
var users []User
_, err := dbmap.Select(&users, "SELECT * FROM User;")
if err == nil {
c.JSON(200, users)
} else {
c.JSON(404, gin.H{"error": "no user(s) into the table"})
}
// curl -i http://localhost:8080/api/v1/users
}
func GetUser(c *gin.Context) {
id := c.Params.ByName("id")
var user User
err := dbmap.SelectOne(&user, "SELECT * FROM User WHERE id=? LIMIT 1;", id)
if err == nil {
user_id, _ := strconv.ParseInt(id, 0, 64)
content := &User{
Id: user_id,
Email: user.Email,
Username: user.Username,
Password: user.Password,
Sex: user.Sex,
Age: user.Age,
}
c.JSON(200, content)
} else {
c.JSON(404, gin.H{"error": "user not found"})
}
// curl -i http://localhost:8080/api/v1/users/1
}
func GetChat(c *gin.Context) {
originID := c.Params.ByName("origin")
destinationID := c.Params.ByName("destination")
wsURL := new(url.URL)
query := wsURL.Query()
query.Add("origin", originID)
query.Add("destination", destinationID)
wsURL.Path = "/ws/chat"
wsURL.RawQuery = query.Encode()
c.JSON(200, gin.H{"websocket_url": wsURL.String()})
// curl -i http://localhost:8080/api/v1/chat/1/2
}
func PostUser(c *gin.Context) {
var user User
c.Bind(&user)
log.Println(user)
if user.Email != "" && user.Username != "" {
if insert, _ := dbmap.Exec(`INSERT INTO User (email, username, password, sex, age) VALUES (?, ?, ?, ?, ?)`, user.Email, user.Username, user.Password, user.Sex, user.Age); insert != nil {
user_id, err := insert.LastInsertId()
if err == nil {
content := &User{
Id: user_id,
Email: user.Email,
Username: user.Username,
Password: user.Password,
Sex: user.Sex,
Age: user.Age,
}
c.JSON(201, content)
} else {
checkErr(err, "Insert failed")
}
}
} else {
c.JSON(400, gin.H{"error": "fields are empty"})
}
// curl -i -X POST -H "Content-Type: application/json" -d "{ \"firstname\": \"Thea\", \"lastname\": \"Queen\" }" http://localhost:8080/api/v1/users
}
func UpdateUser(c *gin.Context) {
id := c.Params.ByName("id")
var user User
err := dbmap.SelectOne(&user, "SELECT * FROM User WHERE id=?;", id)
if err == nil {
var json User
c.Bind(&json)
user_id, _ := strconv.ParseInt(id, 0, 64)
user := User{
Id: user_id,
Email: json.Email,
Username: json.Username,
Password: json.Password,
Sex: json.Sex,
Age: json.Age,
}
if user.Email != "" && user.Username != "" {
_, err = dbmap.Update(&user)
if err == nil {
c.JSON(200, user)
} else {
checkErr(err, "Updated failed")
}
} else {
c.JSON(400, gin.H{"error": "fields are empty"})
}
} else {
c.JSON(404, gin.H{"error": "user not found"})
}
// curl -i -X PUT -H "Content-Type: application/json" -d "{ \"firstname\": \"Thea\", \"lastname\": \"Merlyn\" }" http://localhost:8080/api/v1/users/1
}
func DeleteUser(c *gin.Context) {
id := c.Params.ByName("id")
var user User
err := dbmap.SelectOne(&user, "SELECT * FROM User WHERE id=?;", id)
if err == nil {
_, err = dbmap.Delete(&user)
if err == nil {
c.JSON(200, gin.H{"id #" + id: "deleted"})
} else {
checkErr(err, "Delete failed")
}
} else {
c.JSON(404, gin.H{"error": "user not found"})
}
// curl -i -X DELETE http://localhost:8080/api/v1/users/1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment