forked from kataras/iris
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
114 lines (95 loc) · 2.55 KB
/
main.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
package main // Look README.md
import (
"context"
"database/sql"
"fmt"
"os"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/basicauth"
_ "github.com/go-sql-driver/mysql" // lint: mysql driver.
)
// User is just an example structure of a user,
// it MUST contain a Username and Password exported fields
// or/and complete the basicauth.User interface.
type User struct {
ID int64 `db:"id" json:"id"`
Username string `db:"username" json:"username"`
Password string `db:"password" json:"password"`
Email string `db:"email" json:"email"`
}
// GetUsername returns the Username field.
func (u User) GetUsername() string {
return u.Username
}
// GetPassword returns the Password field.
func (u User) GetPassword() string {
return u.Password
}
func main() {
dsn := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?parseTime=true&charset=utf8mb4&collation=utf8mb4_unicode_ci",
getenv("MYSQL_USER", "user_myapp"),
getenv("MYSQL_PASSWORD", "dbpassword"),
getenv("MYSQL_HOST", "localhost"),
getenv("MYSQL_DATABASE", "myapp"),
)
db, err := connect(dsn)
if err != nil {
panic(err)
}
// Validate a user from database.
allowFunc := func(ctx iris.Context, username, password string) (interface{}, bool) {
user, err := db.getUserByUsernameAndPassword(context.Background(), username, password)
return user, err == nil
}
opts := basicauth.Options{
Realm: basicauth.DefaultRealm,
ErrorHandler: basicauth.DefaultErrorHandler,
Allow: allowFunc,
}
auth := basicauth.New(opts)
app := iris.New()
app.Use(auth)
app.Get("/", index)
app.Listen(":8080")
}
func index(ctx iris.Context) {
user, _ := ctx.User().GetRaw()
// user is a type of main.User
ctx.JSON(user)
}
func getenv(key string, def string) string {
v := os.Getenv(key)
if v == "" {
return def
}
return v
}
type database struct {
*sql.DB
}
func connect(dsn string) (*database, error) {
conn, err := sql.Open("mysql", dsn)
if err != nil {
return nil, err
}
err = conn.Ping()
if err != nil {
conn.Close()
return nil, err
}
return &database{conn}, nil
}
func (db *database) getUserByUsernameAndPassword(ctx context.Context, username, password string) (User, error) {
query := fmt.Sprintf("SELECT * FROM %s WHERE %s = ? AND %s = ? LIMIT 1", "users", "username", "password")
rows, err := db.QueryContext(ctx, query, username, password)
if err != nil {
return User{}, err
}
defer rows.Close()
if !rows.Next() {
return User{}, sql.ErrNoRows
}
var user User
err = rows.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
return user, err
}