mirror of
https://github.com/kataras/iris.git
synced 2025-03-20 22:06:25 +01:00
172 lines
4.5 KiB
Go
172 lines
4.5 KiB
Go
// file: controllers/user_controller.go
|
|
|
|
package controllers
|
|
|
|
import (
|
|
"github.com/kataras/iris/_examples/mvc/login/datamodels"
|
|
"github.com/kataras/iris/_examples/mvc/login/services"
|
|
|
|
"github.com/kataras/iris"
|
|
"github.com/kataras/iris/mvc"
|
|
"github.com/kataras/iris/sessions"
|
|
)
|
|
|
|
// UserController is our /user controller.
|
|
// UserController is responsible to handle the following requests:
|
|
// GET /user/register
|
|
// POST /user/register
|
|
// GET /user/login
|
|
// POST /user/login
|
|
// GET /user/me
|
|
// All HTTP Methods /user/logout
|
|
type UserController struct {
|
|
// context is auto-binded by Iris on each request,
|
|
// remember that on each incoming request iris creates a new UserController each time,
|
|
// so all fields are request-scoped by-default, only dependency injection is able to set
|
|
// custom fields like the Service which is the same for all requests (static binding)
|
|
// and the Session which depends on the current context (dynamic binding).
|
|
Ctx iris.Context
|
|
|
|
// Our UserService, it's an interface which
|
|
// is binded from the main application.
|
|
Service services.UserService
|
|
|
|
// Session, binded using dependency injection from the main.go.
|
|
Session *sessions.Session
|
|
}
|
|
|
|
const userIDKey = "UserID"
|
|
|
|
func (c *UserController) getCurrentUserID() int64 {
|
|
userID, _ := c.Session.GetInt64Default(userIDKey, 0)
|
|
return userID
|
|
}
|
|
|
|
func (c *UserController) isLoggedIn() bool {
|
|
return c.getCurrentUserID() > 0
|
|
}
|
|
|
|
func (c *UserController) logout() {
|
|
c.Session.Destroy()
|
|
}
|
|
|
|
var registerStaticView = mvc.View{
|
|
Name: "user/register.html",
|
|
Data: iris.Map{"Title": "User Registration"},
|
|
}
|
|
|
|
// GetRegister handles GET: http://localhost:8080/user/register.
|
|
func (c *UserController) GetRegister() mvc.Result {
|
|
if c.isLoggedIn() {
|
|
c.logout()
|
|
}
|
|
|
|
return registerStaticView
|
|
}
|
|
|
|
// PostRegister handles POST: http://localhost:8080/user/register.
|
|
func (c *UserController) PostRegister() mvc.Result {
|
|
// get firstname, username and password from the form.
|
|
var (
|
|
firstname = c.Ctx.FormValue("firstname")
|
|
username = c.Ctx.FormValue("username")
|
|
password = c.Ctx.FormValue("password")
|
|
)
|
|
|
|
// create the new user, the password will be hashed by the service.
|
|
u, err := c.Service.Create(password, datamodels.User{
|
|
Username: username,
|
|
Firstname: firstname,
|
|
})
|
|
|
|
// set the user's id to this session even if err != nil,
|
|
// the zero id doesn't matters because .getCurrentUserID() checks for that.
|
|
// If err != nil then it will be shown, see below on mvc.Response.Err: err.
|
|
c.Session.Set(userIDKey, u.ID)
|
|
|
|
return mvc.Response{
|
|
// if not nil then this error will be shown instead.
|
|
Err: err,
|
|
// redirect to /user/me.
|
|
Path: "/user/me",
|
|
// When redirecting from POST to GET request you -should- use this HTTP status code,
|
|
// however there're some (complicated) alternatives if you
|
|
// search online or even the HTTP RFC.
|
|
// Status "See Other" RFC 7231, however iris can automatically fix that
|
|
// but it's good to know you can set a custom code;
|
|
// Code: 303,
|
|
}
|
|
|
|
}
|
|
|
|
var loginStaticView = mvc.View{
|
|
Name: "user/login.html",
|
|
Data: iris.Map{"Title": "User Login"},
|
|
}
|
|
|
|
// GetLogin handles GET: http://localhost:8080/user/login.
|
|
func (c *UserController) GetLogin() mvc.Result {
|
|
if c.isLoggedIn() {
|
|
// if it's already logged in then destroy the previous session.
|
|
c.logout()
|
|
}
|
|
|
|
return loginStaticView
|
|
}
|
|
|
|
// PostLogin handles POST: http://localhost:8080/user/register.
|
|
func (c *UserController) PostLogin() mvc.Result {
|
|
var (
|
|
username = c.Ctx.FormValue("username")
|
|
password = c.Ctx.FormValue("password")
|
|
)
|
|
|
|
u, found := c.Service.GetByUsernameAndPassword(username, password)
|
|
|
|
if !found {
|
|
return mvc.Response{
|
|
Path: "/user/register",
|
|
}
|
|
}
|
|
|
|
c.Session.Set(userIDKey, u.ID)
|
|
|
|
return mvc.Response{
|
|
Path: "/user/me",
|
|
}
|
|
}
|
|
|
|
// GetMe handles GET: http://localhost:8080/user/me.
|
|
func (c *UserController) GetMe() mvc.Result {
|
|
if !c.isLoggedIn() {
|
|
// if it's not logged in then redirect user to the login page.
|
|
return mvc.Response{Path: "/user/login"}
|
|
}
|
|
|
|
u, found := c.Service.GetByID(c.getCurrentUserID())
|
|
if !found {
|
|
// if the session exists but for some reason the user doesn't exist in the "database"
|
|
// then logout and re-execute the function, it will redirect the client to the
|
|
// /user/login page.
|
|
c.logout()
|
|
return c.GetMe()
|
|
}
|
|
|
|
return mvc.View{
|
|
Name: "user/me.html",
|
|
Data: iris.Map{
|
|
"Title": "Profile of " + u.Username,
|
|
"User": u,
|
|
},
|
|
}
|
|
}
|
|
|
|
// AnyLogout handles All/Any HTTP Methods for: http://localhost:8080/user/logout.
|
|
func (c *UserController) AnyLogout() {
|
|
if c.isLoggedIn() {
|
|
c.logout()
|
|
}
|
|
|
|
c.Ctx.Redirect("/user/login")
|
|
}
|