mirror of
https://github.com/kataras/iris.git
synced 2025-03-20 22:06:25 +01:00
190 lines
5.1 KiB
Go
190 lines
5.1 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/context"
|
|
"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 {
|
|
// mvc.C is just a lightweight lightweight alternative
|
|
// to the "mvc.Controller" controller type,
|
|
// use it when you don't need mvc.Controller's fields
|
|
// (you don't need those fields when you return values from the method functions).
|
|
mvc.C
|
|
|
|
// Our UserService, it's an interface which
|
|
// is binded from the main application.
|
|
Service services.UserService
|
|
|
|
// Session-relative things.
|
|
Manager *sessions.Sessions
|
|
Session *sessions.Session
|
|
}
|
|
|
|
// BeginRequest will set the current session to the controller.
|
|
//
|
|
// Remember: iris.Context and context.Context is exactly the same thing,
|
|
// iris.Context is just a type alias for go 1.9 users.
|
|
// We use context.Context here because we don't need all iris' root functions,
|
|
// when we see the import paths, we make it visible to ourselves that this file is using only the context.
|
|
func (c *UserController) BeginRequest(ctx context.Context) {
|
|
c.C.BeginRequest(ctx)
|
|
|
|
if c.Manager == nil {
|
|
ctx.Application().Logger().Errorf(`UserController: sessions manager is nil, you should bind it`)
|
|
ctx.StopExecution() // dont run the main method handler and any "done" handlers.
|
|
return
|
|
}
|
|
|
|
c.Session = c.Manager.Start(ctx)
|
|
}
|
|
|
|
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.Manager.DestroyByID(c.Session.ID())
|
|
}
|
|
|
|
var registerStaticView = mvc.View{
|
|
Name: "user/register.html",
|
|
Data: context.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: context.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: context.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")
|
|
}
|