Ma Suhyeon

Implement two more APIs

1 - 1 +
2 -# Created by https://www.toptal.com/developers/gitignore/api/go,vscode 2 +# Created by https://www.toptal.com/developers/gitignore/api/go,vscode
3 -# Edit at https://www.toptal.com/developers/gitignore?templates=go,vscode 3 +# Edit at https://www.toptal.com/developers/gitignore?templates=go,vscode
4 - 4 +
5 -### Go ### 5 +### Go ###
6 -# Binaries for programs and plugins 6 +# Binaries for programs and plugins
7 -*.exe 7 +*.exe
8 -*.exe~ 8 +*.exe~
9 -*.dll 9 +*.dll
10 -*.so 10 +*.so
11 -*.dylib 11 +*.dylib
12 - 12 +
13 -# Test binary, built with `go test -c` 13 +# Test binary, built with `go test -c`
14 -*.test 14 +*.test
15 - 15 +
16 -# Output of the go coverage tool, specifically when used with LiteIDE 16 +# Output of the go coverage tool, specifically when used with LiteIDE
17 -*.out 17 +*.out
18 - 18 +
19 -# Dependency directories (remove the comment below to include it) 19 +# Dependency directories (remove the comment below to include it)
20 -# vendor/ 20 +# vendor/
21 - 21 +
22 -### Go Patch ### 22 +### Go Patch ###
23 -/vendor/ 23 +/vendor/
24 -/Godeps/ 24 +/Godeps/
25 - 25 +
26 -### vscode ### 26 +### vscode ###
27 -.vscode/* 27 +.vscode/*
28 -!.vscode/settings.json 28 +!.vscode/settings.json
29 -!.vscode/tasks.json 29 +!.vscode/tasks.json
30 -!.vscode/launch.json 30 +!.vscode/launch.json
31 -!.vscode/extensions.json 31 +!.vscode/extensions.json
32 -*.code-workspace 32 +*.code-workspace
33 - 33 +
34 -# End of https://www.toptal.com/developers/gitignore/api/go,vscode 34 +# End of https://www.toptal.com/developers/gitignore/api/go,vscode
35 - 35 +
36 -__debug_bin 36 +__debug_bin
37 -config.json 37 +config.json
38 data 38 data
...\ No newline at end of file ...\ No newline at end of file
......
1 -package main 1 +package main
2 - 2 +
3 -import ( 3 +import (
4 - "fmt" 4 + "fmt"
5 - "net/http" 5 + "net/http"
6 - 6 +
7 - "github.com/gorilla/mux" 7 + "github.com/gorilla/mux"
8 - 8 +
9 - _ "github.com/go-sql-driver/mysql" 9 + _ "github.com/go-sql-driver/mysql"
10 - "github.com/jmoiron/sqlx" 10 + "github.com/jmoiron/sqlx"
11 -) 11 +)
12 - 12 +
13 -type Prop int 13 +type Prop int
14 - 14 +
15 -const ( 15 +const (
16 - PropUserNo Prop = iota 16 + PropUserNo Prop = iota
17 -) 17 +)
18 - 18 +
19 -type App struct { 19 +type App struct {
20 - Config Config 20 + Config Config
21 - db *sqlx.DB 21 + db *sqlx.DB
22 - router *mux.Router 22 + router *mux.Router
23 -} 23 +}
24 - 24 +
25 -func NewApp(config Config) *App { 25 +func NewApp(config Config) *App {
26 - app := new(App) 26 + app := new(App)
27 - app.Config = config 27 + app.Config = config
28 - 28 +
29 - dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s", config.Database.User, config.Database.Password, config.Database.Host, config.Database.Name) 29 + dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s", config.Database.User, config.Database.Password, config.Database.Host, config.Database.Name)
30 - app.db = sqlx.MustOpen("mysql", dsn) 30 + app.db = sqlx.MustOpen("mysql", dsn)
31 - 31 +
32 - app.router = mux.NewRouter() 32 + app.router = mux.NewRouter()
33 - app.router.HandleFunc("/users", app.PostUsers).Methods("POST") 33 + app.router.HandleFunc("/users", app.PostUsers).Methods("POST")
34 - app.router.HandleFunc("/users/tokens", app.PostTokens).Methods("POST") 34 + app.router.HandleFunc("/users/tokens", app.PostTokens).Methods("POST")
35 - app.router.Handle("/extractions", app.WithAuth(app.PostExtractions)).Methods("Post") 35 + app.router.Handle("/extractions", app.WithAuth(app.PostExtractions)).Methods("Post")
36 - 36 + app.router.HandleFunc("/extractions/{file}/calls", app.GetCalls).Methods("GET")
37 - return app 37 + app.router.HandleFunc("/extractions/{file}/messages", app.GetMessages).Methods("GET")
38 -} 38 + app.router.HandleFunc("/extractions/{file}/calls/analyses", app.GetCallsAnalyses).Methods("GET")
39 - 39 + app.router.HandleFunc("/extractions/{file}/apps/analyses", app.GetAppsAnalyses).Methods("GET")
40 -func (app *App) Serve() { 40 + app.router.HandleFunc("/extractions/{file}/messages/analyses", app.GetMessagesAnalyses).Methods("GET")
41 - http.ListenAndServe(fmt.Sprintf(":%d", app.Config.Port), app.router) 41 +
42 -} 42 + return app
43 +}
44 +
45 +func (app *App) Serve() {
46 + http.ListenAndServe(fmt.Sprintf(":%d", app.Config.Port), app.router)
47 +}
......
1 -package main 1 +package main
2 - 2 +
3 -import ( 3 +import (
4 - "encoding/json" 4 + "encoding/json"
5 - "io/ioutil" 5 + "io/ioutil"
6 -) 6 +)
7 - 7 +
8 -type Config struct { 8 +type Config struct {
9 - Port int `json:"port"` 9 + Port int `json:"port"`
10 - Database struct { 10 + Database struct {
11 - Host string `json:"host"` 11 + Host string `json:"host"`
12 - Name string `json:"name"` 12 + Name string `json:"name"`
13 - User string `json:"user"` 13 + User string `json:"user"`
14 - Password string `json:"password"` 14 + Password string `json:"password"`
15 - } `json:"database"` 15 + } `json:"database"`
16 - TokenSecret string `json:"token_secret"` 16 + TokenSecret string `json:"token_secret"`
17 -} 17 +}
18 - 18 +
19 -func LoadConfig(path string) (Config, error) { 19 +func LoadConfig(path string) (Config, error) {
20 - config := Config{} 20 + config := Config{}
21 - 21 +
22 - data, err := ioutil.ReadFile(path) 22 + data, err := ioutil.ReadFile(path)
23 - if err == nil { 23 + if err == nil {
24 - err = json.Unmarshal(data, &config) 24 + err = json.Unmarshal(data, &config)
25 - } 25 + }
26 - 26 +
27 - return config, err 27 + return config, err
28 -} 28 +}
......
1 +package main
2 +
3 +import (
4 + "fmt"
5 + "net/http"
6 + "time"
7 +
8 + "github.com/gorilla/mux"
9 + "github.com/jmoiron/sqlx"
10 +
11 + _ "github.com/mattn/go-sqlite3"
12 +)
13 +
14 +type Call struct {
15 + ID int `json:"id" db:"id"`
16 + Type int `json:"type" db:"type"`
17 + Name *string `json:"name" db:"name"`
18 + Number int `json:"number" db:"number"`
19 + Duration int `json:"duration" db:"duration"`
20 + Date Time `json:"date" db:"date"`
21 +}
22 +
23 +func (app *App) GetCalls(w http.ResponseWriter, r *http.Request) {
24 + vars := mux.Vars(r)
25 +
26 + calls := []Call{}
27 +
28 + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"]))
29 + if err != nil {
30 + WriteError(w, http.StatusInternalServerError, "Could not open db file")
31 + return
32 + }
33 + defer db.Close()
34 +
35 + query := `SELECT * FROM calllog`
36 + fmt.Println(db.Select(&calls, query))
37 +
38 + WriteJson(w, calls)
39 +}
40 +
41 +type CallStats struct {
42 + Number string `json:"number" db:"number"`
43 + Name *string `json:"name" db:"name"`
44 + Incoming int `json:"incoming" db:"incoming"`
45 + Outgoing int `json:"outgoing" db:"outgoing"`
46 + Duration int `json:"duration" db:"duration"`
47 +}
48 +
49 +func (app *App) GetCallsAnalyses(w http.ResponseWriter, r *http.Request) {
50 + vars := mux.Vars(r)
51 +
52 + calls := []CallStats{}
53 +
54 + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"]))
55 + if err != nil {
56 + WriteError(w, http.StatusInternalServerError, "Could not open db file")
57 + return
58 + }
59 + defer db.Close()
60 +
61 + query := `SELECT number, name,
62 + (SELECT COUNT(1) FROM calllog s WHERE s.number=c.number AND s.type=1) incoming,
63 + (SELECT COUNT(1) FROM calllog s WHERE s.number=c.number AND s.type=2) outgoing,
64 + SUM(duration) duration
65 + FROM calllog c GROUP BY number ORDER BY duration DESC`
66 + db.Select(&calls, query)
67 +
68 + WriteJson(w, calls)
69 +}
70 +
71 +type AppInfo struct {
72 + PackageName string `json:"package_name" db:"packagename"`
73 + Name string `json:"name" db:"name"`
74 + Version string `json:"version" db:"version"`
75 + WifiUsage int `json:"wifi_usage" db:"wifiusage"`
76 + CellularUsage int `json:"cellular_usage" db:"cellularusage"`
77 + LastUsed time.Time `json:"last_used" db:"lasttimeused"`
78 + ForegroundTime int `json:"foreground_time" db:"totaltimeforeground"`
79 +}
80 +
81 +func (app *App) GetAppsAnalyses(w http.ResponseWriter, r *http.Request) {
82 + vars := mux.Vars(r)
83 +
84 + apps := []AppInfo{}
85 + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"]))
86 + if err != nil {
87 + WriteError(w, http.StatusInternalServerError, "Could not open db file")
88 + return
89 + }
90 + defer db.Close()
91 +
92 + query := `SELECT
93 + a.packagename, a.name, a.version, a.wifiusage, a.cellularusage,
94 + u.lasttimeused, u.totaltimeforeground
95 + FROM AppInfo a JOIN AppUsageYear u
96 + ORDER BY totaltimeforeground DESC`
97 + db.Select(&apps, query)
98 +
99 + WriteJson(w, apps)
100 +}
101 +
102 +type Message struct {
103 + ID int `json:"id" db:"mid"`
104 + Type int `json:"type" db:"type"`
105 + Address string `json:"address"`
106 + Body string `json:"body"`
107 + Date Time `json:"date" db:"date"`
108 +}
109 +
110 +func (app *App) GetMessages(w http.ResponseWriter, r *http.Request) {
111 + vars := mux.Vars(r)
112 +
113 + messages := []Message{}
114 + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"]))
115 + if err != nil {
116 + WriteError(w, http.StatusInternalServerError, "Could not open db file")
117 + return
118 + }
119 + defer db.Close()
120 +
121 + query := `SELECT mid, type, address, body, date FROM sms`
122 + db.Select(&messages, query)
123 +
124 + WriteJson(w, messages)
125 +}
126 +
127 +type MessageStats struct {
128 + Address string `json:"number" db:"number"`
129 + Receive int `json:"incoming" db:"incoming"`
130 + Send int `json:"outgoing" db:"outgoing"`
131 +}
132 +
133 +func (app *App) GetMessagesAnalyses(w http.ResponseWriter, r *http.Request) {
134 + vars := mux.Vars(r)
135 +
136 + messages := []MessageStats{}
137 + db, err := sqlx.Connect("sqlite3", fmt.Sprintf("data/1/%s", vars["file"]))
138 + if err != nil {
139 + WriteError(w, http.StatusInternalServerError, "Could not open db file")
140 + return
141 + }
142 + defer db.Close()
143 +
144 + query := `SELECT address,
145 + (SELECT COUNT(1) FROM sms m WHERE m.address=s.address AND m.type=1) receive,
146 + (SELECT COUNT(1) FROM sms m WHERE m.address=s.address AND m.type=2) send
147 + FROM sms s GROUP BY address ORDER BY receive + send DESC`
148 + db.Select(&messages, query)
149 +
150 + WriteJson(w, messages)
151 +}
1 -package main 1 +package main
2 - 2 +
3 -import ( 3 +import (
4 - "fmt" 4 + "fmt"
5 - "io" 5 + "io"
6 - "net/http" 6 + "net/http"
7 - "os" 7 + "os"
8 - "strings" 8 + "strings"
9 - 9 +
10 - "github.com/google/uuid" 10 + "github.com/google/uuid"
11 -) 11 +)
12 - 12 +
13 -func (app *App) PostExtractions(w http.ResponseWriter, r *http.Request) { 13 +func (app *App) PostExtractions(w http.ResponseWriter, r *http.Request) {
14 - userNo := r.Context().Value(PropUserNo).(uint64) 14 + userNo := r.Context().Value(PropUserNo).(uint64)
15 - r.ParseMultipartForm(32 << 20) 15 + r.ParseMultipartForm(32 << 20)
16 - 16 +
17 - form, _, err := r.FormFile("file") 17 + form, _, err := r.FormFile("file")
18 - if err != nil { 18 + if err != nil {
19 - WriteError(w, http.StatusInternalServerError, "Unknown error") 19 + WriteError(w, http.StatusInternalServerError, "Unknown error")
20 - return 20 + return
21 - } 21 + }
22 - 22 +
23 - defer form.Close() 23 + defer form.Close()
24 - 24 +
25 - dir := fmt.Sprintf("data/%d", userNo) 25 + dir := fmt.Sprintf("data/%d", userNo)
26 - os.MkdirAll(dir, 0644) 26 + os.MkdirAll(dir, 0644)
27 - 27 +
28 - name := strings.Replace(uuid.New().String(), "-", "", -1) 28 + name := strings.Replace(uuid.New().String(), "-", "", -1)
29 - file, err := os.Create(fmt.Sprintf("%s/%s", dir, name)) 29 + file, err := os.Create(fmt.Sprintf("%s/%s", dir, name))
30 - if err != nil { 30 + if err != nil {
31 - WriteError(w, http.StatusInternalServerError, "Unknown error") 31 + WriteError(w, http.StatusInternalServerError, "Unknown error")
32 - return 32 + return
33 - } 33 + }
34 - defer file.Close() 34 + defer file.Close()
35 - 35 +
36 - _, err = io.Copy(file, form) 36 + _, err = io.Copy(file, form)
37 - if err != nil { 37 + if err != nil {
38 - WriteError(w, http.StatusInternalServerError, "Unknown error") 38 + WriteError(w, http.StatusInternalServerError, "Unknown error")
39 - return 39 + return
40 - } 40 + }
41 - 41 +
42 - w.Write([]byte("success")) 42 + w.Write([]byte("success"))
43 -} 43 +}
......
...@@ -8,5 +8,6 @@ require ( ...@@ -8,5 +8,6 @@ require (
8 github.com/google/uuid v1.1.2 8 github.com/google/uuid v1.1.2
9 github.com/gorilla/mux v1.8.0 9 github.com/gorilla/mux v1.8.0
10 github.com/jmoiron/sqlx v1.2.0 10 github.com/jmoiron/sqlx v1.2.0
11 + github.com/mattn/go-sqlite3 v1.9.0
11 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 12 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
12 ) 13 )
......
...@@ -11,6 +11,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 ...@@ -11,6 +11,7 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
11 github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= 11 github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
12 github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= 12 github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
13 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 13 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
14 +github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
14 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 15 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
15 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 16 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
16 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= 17 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
......
1 -package main 1 +package main
2 - 2 +
3 -import ( 3 +import (
4 - "log" 4 + "log"
5 -) 5 +)
6 - 6 +
7 -func main() { 7 +func main() {
8 - config, err := LoadConfig("config.json") 8 + config, err := LoadConfig("config.json")
9 - if err != nil { 9 + if err != nil {
10 - log.Fatal(err) 10 + log.Fatal(err)
11 - } 11 + }
12 - 12 +
13 - app := NewApp(config) 13 + app := NewApp(config)
14 - app.Serve() 14 + app.Serve()
15 -} 15 +}
......
1 +package main
2 +
3 +import (
4 + "time"
5 +)
6 +
7 +type Time time.Time
8 +
9 +func (t *Time) Scan(v interface{}) error {
10 + p, err := time.Parse("2006-01-02 15:04:05", string(v.([]byte)))
11 + *t = Time(p)
12 + return err
13 +}
14 +
15 +func (t *Time) MarshalJSON() ([]byte, error) {
16 + return time.Time(*t).MarshalJSON()
17 +}
1 -package main 1 +package main
2 - 2 +
3 -import ( 3 +import (
4 - "context" 4 + "context"
5 - "encoding/json" 5 + "encoding/json"
6 - "net/http" 6 + "net/http"
7 - "strings" 7 + "strings"
8 - "time" 8 + "time"
9 - 9 +
10 - "github.com/dgrijalva/jwt-go" 10 + "github.com/dgrijalva/jwt-go"
11 - "github.com/go-sql-driver/mysql" 11 + "github.com/go-sql-driver/mysql"
12 - "golang.org/x/crypto/sha3" 12 + "golang.org/x/crypto/sha3"
13 -) 13 +)
14 - 14 +
15 -type User struct { 15 +type User struct {
16 - No uint64 `json:"no"` 16 + No uint64 `json:"no"`
17 - ID string `json:"id"` 17 + ID string `json:"id"`
18 - Name string `json:"name"` 18 + Name string `json:"name"`
19 - CreatedAt time.Time `json:"created_at"` 19 + CreatedAt time.Time `json:"created_at"`
20 - ExpiredAt time.Time `json:"expired_at"` 20 + ExpiredAt time.Time `json:"expired_at"`
21 -} 21 +}
22 - 22 +
23 -func (app *App) PostUsers(w http.ResponseWriter, r *http.Request) { 23 +func (app *App) PostUsers(w http.ResponseWriter, r *http.Request) {
24 - body := make(map[string]interface{}) 24 + body := make(map[string]interface{})
25 - err := json.NewDecoder(r.Body).Decode(&body) 25 + err := json.NewDecoder(r.Body).Decode(&body)
26 - if err != nil { 26 + if err != nil {
27 - WriteError(w, http.StatusBadRequest, "Failed to parse request json") 27 + WriteError(w, http.StatusBadRequest, "Failed to parse request json")
28 - return 28 + return
29 - } 29 + }
30 - 30 +
31 - hash := sha3.Sum256([]byte(body["password"].(string))) 31 + hash := sha3.Sum256([]byte(body["password"].(string)))
32 - 32 +
33 - res, err := app.db.Exec("INSERT INTO users (`id`, `password`, `name`) VALUES (?, ?, ?)", body["id"], hash[:], body["name"]) 33 + res, err := app.db.Exec("INSERT INTO users (`id`, `password`, `name`) VALUES (?, ?, ?)", body["id"], hash[:], body["name"])
34 - if err != nil { 34 + if err != nil {
35 - if merr, ok := err.(*mysql.MySQLError); ok { 35 + if merr, ok := err.(*mysql.MySQLError); ok {
36 - if merr.Number == 1062 { 36 + if merr.Number == 1062 {
37 - WriteError(w, http.StatusConflict, "Already registered") 37 + WriteError(w, http.StatusConflict, "Already registered")
38 - return 38 + return
39 - } 39 + }
40 - } 40 + }
41 - 41 +
42 - WriteError(w, http.StatusInternalServerError, "Failed to register") 42 + WriteError(w, http.StatusInternalServerError, "Failed to register")
43 - return 43 + return
44 - } 44 + }
45 - 45 +
46 - no, _ := res.LastInsertId() 46 + no, _ := res.LastInsertId()
47 - WriteJson(w, map[string]interface{}{"user_no": no}) 47 + WriteJson(w, map[string]interface{}{"user_no": no})
48 -} 48 +}
49 - 49 +
50 -type AuthClaims struct { 50 +type AuthClaims struct {
51 - UserNo uint64 `json:"user_no"` 51 + UserNo uint64 `json:"user_no"`
52 - jwt.StandardClaims 52 + jwt.StandardClaims
53 -} 53 +}
54 - 54 +
55 -func (app *App) PostTokens(w http.ResponseWriter, r *http.Request) { 55 +func (app *App) PostTokens(w http.ResponseWriter, r *http.Request) {
56 - body := make(map[string]interface{}) 56 + body := make(map[string]interface{})
57 - err := json.NewDecoder(r.Body).Decode(&body) 57 + err := json.NewDecoder(r.Body).Decode(&body)
58 - if err != nil { 58 + if err != nil {
59 - WriteError(w, http.StatusBadRequest, "Failed to parse request json") 59 + WriteError(w, http.StatusBadRequest, "Failed to parse request json")
60 - return 60 + return
61 - } 61 + }
62 - 62 +
63 - hash := sha3.Sum256([]byte(body["password"].(string))) 63 + hash := sha3.Sum256([]byte(body["password"].(string)))
64 - rows, err := app.db.Query("SELECT `no` FROM users WHERE `id`=? AND `password`=?", body["id"], hash[:]) 64 + rows, err := app.db.Query("SELECT `no` FROM users WHERE `id`=? AND `password`=?", body["id"], hash[:])
65 - if err != nil { 65 + if err != nil {
66 - WriteError(w, http.StatusInternalServerError, "Failed to register") 66 + WriteError(w, http.StatusInternalServerError, "Failed to register")
67 - return 67 + return
68 - } 68 + }
69 - 69 +
70 - if !rows.Next() { 70 + if !rows.Next() {
71 - WriteError(w, http.StatusUnauthorized, "Login failed") 71 + WriteError(w, http.StatusUnauthorized, "Login failed")
72 - return 72 + return
73 - } 73 + }
74 - 74 +
75 - no := uint64(0) 75 + no := uint64(0)
76 - rows.Scan(&no) 76 + rows.Scan(&no)
77 - 77 +
78 - token := jwt.NewWithClaims(jwt.SigningMethodHS256, AuthClaims{UserNo: no}) 78 + token := jwt.NewWithClaims(jwt.SigningMethodHS256, AuthClaims{UserNo: no})
79 - auth, err := token.SignedString([]byte(app.Config.TokenSecret)) 79 + auth, err := token.SignedString([]byte(app.Config.TokenSecret))
80 - if err != nil { 80 + if err != nil {
81 - WriteError(w, http.StatusInternalServerError, "Login failed") 81 + WriteError(w, http.StatusInternalServerError, "Login failed")
82 - return 82 + return
83 - } 83 + }
84 - 84 +
85 - WriteJson(w, map[string]interface{}{"token": auth}) 85 + WriteJson(w, map[string]interface{}{"token": auth})
86 -} 86 +}
87 - 87 +
88 -func (app *App) WithAuth(next func(http.ResponseWriter, *http.Request)) http.Handler { 88 +func (app *App) WithAuth(next func(http.ResponseWriter, *http.Request)) http.Handler {
89 - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 89 + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
90 - auth := r.Header.Get("Authorization") 90 + auth := r.Header.Get("Authorization")
91 - if len(auth) > 6 && strings.Index(auth, "Bearer ") == 0 { 91 + if len(auth) > 6 && strings.Index(auth, "Bearer ") == 0 {
92 - token, err := jwt.ParseWithClaims(auth[7:], &AuthClaims{}, func(token *jwt.Token) (interface{}, error) { 92 + token, err := jwt.ParseWithClaims(auth[7:], &AuthClaims{}, func(token *jwt.Token) (interface{}, error) {
93 - return []byte(app.Config.TokenSecret), nil 93 + return []byte(app.Config.TokenSecret), nil
94 - }) 94 + })
95 - 95 +
96 - if err == nil { 96 + if err == nil {
97 - claims := token.Claims.(*AuthClaims) 97 + claims := token.Claims.(*AuthClaims)
98 - ctx := context.WithValue(r.Context(), PropUserNo, claims.UserNo) 98 + ctx := context.WithValue(r.Context(), PropUserNo, claims.UserNo)
99 - next(w, r.WithContext(ctx)) 99 + next(w, r.WithContext(ctx))
100 - return 100 + return
101 - } 101 + }
102 - } 102 + }
103 - 103 +
104 - WriteError(w, http.StatusUnauthorized, "Authorization failed") 104 + WriteError(w, http.StatusUnauthorized, "Authorization failed")
105 - }) 105 + })
106 -} 106 +}
......
1 -package main 1 +package main
2 - 2 +
3 -import ( 3 +import (
4 - "encoding/json" 4 + "encoding/json"
5 - "net/http" 5 + "net/http"
6 -) 6 +)
7 - 7 +
8 -func WriteJson(w http.ResponseWriter, data interface{}) { 8 +func WriteJson(w http.ResponseWriter, data interface{}) {
9 - w.Header().Set("Content-Type", "application/json") 9 + w.Header().Set("Content-Type", "application/json")
10 - json.NewEncoder(w).Encode(data) 10 + json.NewEncoder(w).Encode(data)
11 -} 11 +}
12 - 12 +
13 -func WriteError(w http.ResponseWriter, status int, message string) { 13 +func WriteError(w http.ResponseWriter, status int, message string) {
14 - w.Header().Set("Content-Type", "application/json") 14 + w.Header().Set("Content-Type", "application/json")
15 - w.WriteHeader(status) 15 + w.WriteHeader(status)
16 - json.NewEncoder(w).Encode(map[string]interface{}{"msg": message}) 16 + json.NewEncoder(w).Encode(map[string]interface{}{"msg": message})
17 -} 17 +}
......