diff --git a/__debug_bin b/__debug_bin
deleted file mode 100755
index 9383cd2b59178ea8f95c1419aefe68f567ab55fc..0000000000000000000000000000000000000000
Binary files a/__debug_bin and /dev/null differ
diff --git a/data/test.db b/data/test.db
index 8616989263916b184bb39769ac9d9f20f3a3e14e..6632317d0cb45ca56b798a9830c7a18f68b98d9d 100644
Binary files a/data/test.db and b/data/test.db differ
diff --git a/data/users.db b/data/users.db
index ae68077b7f8523f5d7577885f3697c70c99ce8e9..aacb808a6df9d089bef233ea44695d3a7fc84678 100644
Binary files a/data/users.db and b/data/users.db differ
diff --git a/go.mod b/go.mod
index 5e2f5078e3d5ed48351c4ae2518b0f4753fec7e1..6ecac3ab834527f4e3bab3a9b21236911fd22e19 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module forge.grandlyon.com/apoyen/elections
 go 1.14
 
 require (
-	forge.grandlyon.com/apoyen/sdk-go v0.0.0-20200504124323-b515b737f420
+	forge.grandlyon.com/apoyen/sdk-go v0.0.0-20200506130516-44169b4175cf
 	github.com/jinzhu/gorm v1.9.12
 	golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
 	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
diff --git a/go.sum b/go.sum
index e6d2e9007e2ac22eaa075a0be7a3bca129e728ff..23c89f0b890bed63dfc48cd7d8467a6e1732ed6f 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,8 @@
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 forge.grandlyon.com/apoyen/sdk-go v0.0.0-20200504124323-b515b737f420 h1:zMXCCzbXelZF53D4+YaHFwld3WYPlYaXaJdYwCWj3dg=
 forge.grandlyon.com/apoyen/sdk-go v0.0.0-20200504124323-b515b737f420/go.mod h1:ajJR/1lQlFldcLXFE+PhHNEL/KhU0kW7bTeVUnaM574=
+forge.grandlyon.com/apoyen/sdk-go v0.0.0-20200506130516-44169b4175cf h1:qPCX0bepDzHy/JO1exHZY0i3M5+j0X86uY+11vevUSE=
+forge.grandlyon.com/apoyen/sdk-go v0.0.0-20200506130516-44169b4175cf/go.mod h1:ajJR/1lQlFldcLXFE+PhHNEL/KhU0kW7bTeVUnaM574=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
diff --git a/internal/auth/auth.go b/internal/auth/auth.go
index 5ae0952bcca906a21760a3e809e47297227100e8..ce8a4fe3e419e1971e6bbe19b02afbdcfa5133a9 100644
--- a/internal/auth/auth.go
+++ b/internal/auth/auth.go
@@ -27,11 +27,9 @@ type User struct {
 	ID           int    `json:"id,omitempty"`
 	IDOAuth      string `json:"idOAuth,omitempry"`
 	Login        string `json:"login"`
-	DisplayName  string `json:"displayName,omitempty"`
 	Role         string `json:"role"`
 	IsAdmin      bool   `json:"isAdmin,omitempty"`
 	Name         string `json:"name,omitempty"`
-	Surname      string `json:"surname,omitempty"`
 	PasswordHash string `json:"-"`
 	Password     string `json:"password,omitempty"`
 }
diff --git a/internal/auth/inmemory.go b/internal/auth/inmemory.go
index 70aab983373267b572f4fb1c7aae5f8b2f2c4ad7..6cef4810e1478e0244b8b9dd53e65f952eae7c71 100644
--- a/internal/auth/inmemory.go
+++ b/internal/auth/inmemory.go
@@ -50,7 +50,7 @@ func (m Manager) HandleInMemoryLogin(w http.ResponseWriter, r *http.Request) {
 	tokenData := TokenData{User: User{ID: user.ID, Login: user.Login, Role: user.Role}, XSRFToken: xsrfToken}
 	tokens.Manager.StoreData(tokenData, m.Hostname, authTokenKey, 24*time.Hour, w)
 	// Log the connexion
-	log.Logger.Printf("| %v (%v %v) | Login success | %v | %v", user.Login, user.Name, user.Surname, r.RemoteAddr, log.GetCityAndCountryFromRequest(r))
+	log.Logger.Printf("| %v (%v) | Login success | %v | %v", user.Login, user.Name, r.RemoteAddr, log.GetCityAndCountryFromRequest(r))
 }
 
 // ByID implements sort.Interface for []User based on the ID field
@@ -150,10 +150,13 @@ func (d *DataHandler) UpdateUser(w http.ResponseWriter, req *http.Request) {
 		}
 		user.IDOAuth = newUser.IDOAuth
 		user.Login = newUser.Login
-		user.DisplayName = newUser.DisplayName
 		user.Name = newUser.Name
-		user.Surname = newUser.Surname
 		user.Role = newUser.Role
+		if user.Role == "ADMIN" {
+			user.IsAdmin = true
+		} else {
+			user.IsAdmin = false
+		}
 		if newUser.Password != "" {
 			hash, err := bcrypt.GenerateFromPassword([]byte(newUser.Password), bcrypt.DefaultCost)
 			if err != nil {
diff --git a/internal/auth/oauth2.go b/internal/auth/oauth2.go
index 854c7575234df45912c6a8800f8cb7f162d37a38..ca1dc276977b1bc395f87e0dfae355897818d5e6 100644
--- a/internal/auth/oauth2.go
+++ b/internal/auth/oauth2.go
@@ -140,7 +140,7 @@ func (m Manager) HandleOAuth2Callback() http.Handler {
 		tokenData := TokenData{User: user, XSRFToken: xsrfToken}
 		tokens.Manager.StoreData(tokenData, m.Hostname, authTokenKey, 24*time.Hour, w)
 		// Log the connexion
-		log.Logger.Printf("| %v (%v %v) | Login success | %v | %v", user.Login, user.Name, user.Surname, req.RemoteAddr, log.GetCityAndCountryFromRequest(req))
+		log.Logger.Printf("| %v (%v) | Login success | %v | %v", user.Login, user.Name, req.RemoteAddr, log.GetCityAndCountryFromRequest(req))
 		// Redirect
 		http.Redirect(w, r, "/", http.StatusFound)
 	}
@@ -163,30 +163,21 @@ func (d *DataHandler) addUserInMemory(userOauth2 UserOAuth2) (User, error) {
 	for _, userRole := range userOauth2.Groups {
 		if userRole != "" && (userRole == os.Getenv("ADMIN_GROUP")) {
 			user.Role = "ADMIN"
+			user.IsAdmin = true
+			break
 		} else if userRole != "" && (userRole == os.Getenv("VISUALIZER_GROUP")) {
 			user.Role = "VISUALIZER"
+			user.IsAdmin = false
+			break
 		} else {
+			fmt.Println(os.Getenv("ADMIN_GROUP") + " " + userRole)
 			return user, errors.New("user not in an app group")
 		}
 	}
 	user.IDOAuth = userOauth2.ID
 	user.Login = userOauth2.Login
-	user.DisplayName = userOauth2.DisplayName
 	user.Name = userOauth2.Name
-	user.Surname = userOauth2.Surname
 
-	var users []User
-	err := common.Load(UsersFile, &users)
-	if err != nil {
-		return user, errors.New("Error on loading user")
-	}
-	// Select the new id for the user
-	user.ID = 1
-	for _, val := range users {
-		if user.ID <= val.ID {
-			user.ID = val.ID + 1
-		}
-	}
 	// Sauvegarder l'utilisateur dans InMemory
 	d.createUser(user)
 	return user, nil
diff --git a/internal/models/capturer.go b/internal/models/capturer.go
new file mode 100644
index 0000000000000000000000000000000000000000..f048bcbbfafbe3b5c661608a50f5944d1eb20651
--- /dev/null
+++ b/internal/models/capturer.go
@@ -0,0 +1,143 @@
+package models
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"strconv"
+	"strings"
+
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
+)
+
+// HandleCapturer handle API calls on Capturer
+func (d *DataHandler) HandleCapturer(w http.ResponseWriter, r *http.Request) {
+	id, _ := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/Capturer/"))
+	switch method := r.Method; method {
+	case "GET":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.getCapturerAdmin(w, r, id)
+		case "CAPTURER":
+			d.getCapturerCapturer(w, r, id)
+		case "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	case "POST":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.postCapturerAdmin(w, r)
+		case "CAPTURER", "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+
+	case "PUT":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.putCapturerAdmin(w, r, id)
+		case "CAPTURER", "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	case "DELETE":
+		switch auth.GetLoggedUserTechnical(w, r).Role {
+		case "ADMIN":
+			d.deleteCapturerAdmin(w, r, id)
+		case "CAPTURER", "VISUALIZER":
+			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
+		default:
+			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
+		}
+	default:
+		http.Error(w, "method not allowed", 400)
+	}
+}
+
+func (d *DataHandler) getCapturerAdmin(w http.ResponseWriter, r *http.Request, id int) {
+	if id != 0 {
+		var o Capturer
+		if err := d.db.Preload("DeskRounds").First(&o, id).Error; err != nil {
+			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+			return
+		}
+		json.NewEncoder(w).Encode(o)
+	} else {
+		var o []Capturer
+		d.db.Preload("DeskRounds").Find(&o)
+		json.NewEncoder(w).Encode(o)
+	}
+}
+
+func (d *DataHandler) getCapturerCapturer(w http.ResponseWriter, r *http.Request, id int) {
+	user := d.getLoggedUser(w, r).(Capturer)
+	fmt.Println(user)
+	if id != 0 {
+		var o Capturer
+		if err := d.db.Preload("DeskRounds").First(&o, id).Error; err != nil {
+			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+			return
+		}
+		// fmt.Println(o)
+		if o.UserID != user.UserID {
+			http.Error(w, ErrorCannotAccessRessource, http.StatusForbidden)
+			return
+		}
+		json.NewEncoder(w).Encode(o)
+	} else {
+		var o []Capturer
+		d.db.Preload("DeskRounds").Where("id = ?", user.ID).Find(&o)
+		json.NewEncoder(w).Encode(o)
+	}
+}
+
+func (d *DataHandler) postCapturerAdmin(w http.ResponseWriter, r *http.Request) {
+	var o Capturer
+	err := json.NewDecoder(r.Body).Decode(&o)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+	var capturer Capturer
+	if err := d.db.Where("user_id = ?", o.UserID).First(&capturer).Error; err == nil {
+		http.Error(w, "UserID is already bind to a Capturer", http.StatusInternalServerError)
+		return
+	}
+	d.db.Create(&o)
+	d.db.Last(&o)
+	json.NewEncoder(w).Encode(o)
+
+}
+
+func (d *DataHandler) putCapturerAdmin(w http.ResponseWriter, r *http.Request, id int) {
+	var o Capturer
+	if err := d.db.Preload("DeskRounds").First(&o, id).Error; err != nil {
+		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+		return
+	}
+	var capturer Capturer
+	err := json.NewDecoder(r.Body).Decode(&capturer)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+	}
+	o.Name = capturer.Name
+	d.db.Save(&o)
+	json.NewEncoder(w).Encode(o)
+
+}
+
+func (d *DataHandler) deleteCapturerAdmin(w http.ResponseWriter, r *http.Request, id int) {
+	if id != 0 {
+		var o Capturer
+		if err := d.db.First(&o, id).Error; err != nil {
+			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+			return
+		}
+		d.db.Delete(&o)
+	} else {
+		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
+	}
+}
diff --git a/internal/models/models.go b/internal/models/models.go
index 24bcd4fc1086862358bacab665703f928c9e4e23..858791b68c303133d158354ab7e38f6a1ab9af38 100644
--- a/internal/models/models.go
+++ b/internal/models/models.go
@@ -5,6 +5,7 @@ import (
 	"strings"
 	"time"
 
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
 	"github.com/jinzhu/gorm"
 
 	// Needed for sqlite
@@ -16,159 +17,173 @@ type DataHandler struct {
 	db *gorm.DB
 }
 
-// ErrorIDDoesNotExist = "id does not exist"
+// ErrorIDDoesNotExist = "id does not exist" with 404 http.StatusNotFound
 const ErrorIDDoesNotExist = "id does not exist"
 
-// ErrorIDIsMissing = "id is missing"
+// ErrorIDIsMissing = "id is missing" with 404 http.StatusNotFound
 const ErrorIDIsMissing = "id is missing"
 
-// ErrorCannotAccessRessource = "You can not access this ressource"
+// ErrorCannotAccessRessource = "You can not access this ressource" with 403 http.StatusForbidden
 const ErrorCannotAccessRessource = "You can not access this ressource"
 
-// ErrorRoleOfLoggedUser = "Could not get role of logged user"
+// ErrorRoleOfLoggedUser = "Could not get role of logged user" with 500 http.StatusInternalServerError
 const ErrorRoleOfLoggedUser = "Could not get role of logged user"
 
-// ErrorNotAuthorizeMethodOnRessource = "You're not authorize to execute this method on this ressource."
+// ErrorNotAuthorizeMethodOnRessource = "You're not authorize to execute this method on this ressource." with 405 http.StatusMethodNotAllowed
 const ErrorNotAuthorizeMethodOnRessource = "You're not authorize to execute this method on this ressource."
 
-type election struct {
+// Election
+type Election struct {
 	ID         uint       `gorm:"primary_key"`
 	CreatedAt  time.Time  `json:"-"`
 	UpdatedAt  time.Time  `json:"-"`
 	DeletedAt  *time.Time `json:"-"`
-	name       string
-	ballotType string
-	areas      []area
-	rounds     []round
+	Name       string
+	BallotType string
+	Areas      []Area
+	Rounds     []Round
 }
 
-type area struct {
+// Area
+type Area struct {
 	ID         uint       `gorm:"primary_key"`
 	CreatedAt  time.Time  `json:"-"`
 	UpdatedAt  time.Time  `json:"-"`
 	DeletedAt  *time.Time `json:"-"`
-	electionID uint
-	name       string
-	seatNumber uint
-	mapID      string
-	sections   []section
+	ElectionID uint
+	Name       string
+	SeatNumber uint
+	MapID      string
+	Sections   []Section
 }
 
-type section struct {
+// Section
+type Section struct {
 	ID         uint       `gorm:"primary_key"`
 	CreatedAt  time.Time  `json:"-"`
 	UpdatedAt  time.Time  `json:"-"`
 	DeletedAt  *time.Time `json:"-"`
-	areaID     uint
-	name       string
-	seatNumber uint
-	mapID      string
-	desks      []desk
+	AreaID     uint
+	Name       string
+	SeatNumber uint
+	MapID      string
+	Desks      []Desk
 }
 
-type desk struct {
+// Desk
+type Desk struct {
 	ID          uint       `gorm:"primary_key"`
 	CreatedAt   time.Time  `json:"-"`
 	UpdatedAt   time.Time  `json:"-"`
 	DeletedAt   *time.Time `json:"-"`
-	sectionID   uint
-	name        string
-	subscribed  uint
-	witnessDesk bool
+	SectionID   uint
+	Name        string
+	Subscribed  uint
+	WitnessDesk bool
 }
 
-type party struct {
+// Party
+type Party struct {
 	ID            uint       `gorm:"primary_key"`
 	CreatedAt     time.Time  `json:"-"`
 	UpdatedAt     time.Time  `json:"-"`
 	DeletedAt     *time.Time `json:"-"`
-	name          string
-	color         string
-	candidateList []candidateList
+	Name          string
+	Color         string
+	CandidateList []CandidateList
 }
 
-type capturer struct {
+// Capturer
+type Capturer struct {
 	ID         uint       `gorm:"primary_key"`
 	CreatedAt  time.Time  `json:"-"`
 	UpdatedAt  time.Time  `json:"-"`
 	DeletedAt  *time.Time `json:"-"`
-	userID     int        `gorm:"not null;unique"`
-	name       string
-	deskRounds []deskRound
+	UserID     int        `gorm:"not null;unique"`
+	Name       string
+	DeskRounds []DeskRound `gorm:"many2many:capturer_deskrounds;"`
 }
 
-type parameter struct {
+// Parameter
+type Parameter struct {
 	ID                uint       `gorm:"primary_key"`
 	CreatedAt         time.Time  `json:"-"`
 	UpdatedAt         time.Time  `json:"-"`
 	DeletedAt         *time.Time `json:"-"`
-	countBalnkAndNull bool
-	showOnlyCompleted bool
-	showMap           bool
+	CountBalnkAndNull bool
+	ShowOnlyCompleted bool
+	ShowMap           bool
 }
 
-type round struct {
+// Round
+type Round struct {
 	ID             uint       `gorm:"primary_key"`
 	CreatedAt      time.Time  `json:"-"`
 	UpdatedAt      time.Time  `json:"-"`
 	DeletedAt      *time.Time `json:"-"`
-	electionID     uint
-	parameter      parameter
-	name           string
-	date           time.Time
-	tour           uint
-	deskRounds     []deskRound
-	candidateLists []candidateList
+	ElectionID     uint
+	Parameter      Parameter
+	Name           string
+	Date           time.Time
+	Tour           uint
+	DeskRounds     []DeskRound
+	CandidateLists []CandidateList
 }
 
-type deskRound struct {
+// DeskRound
+type DeskRound struct {
 	ID             uint       `gorm:"primary_key"`
 	CreatedAt      time.Time  `json:"-"`
 	UpdatedAt      time.Time  `json:"-"`
 	DeletedAt      *time.Time `json:"-"`
-	roundID        uint
-	completed      bool
-	dateCompletion time.Time
-	validated      bool
-	votes          []vote
+	RoundID        uint
+	Capturers      []Capturer `gorm:"many2many:capturer_deskrounds;"`
+	Completed      bool
+	DateCompletion time.Time
+	Validated      bool
+	Votes          []Vote
 }
-type candidateList struct {
+
+// CandidateList
+type CandidateList struct {
 	ID         uint       `gorm:"primary_key"`
 	CreatedAt  time.Time  `json:"-"`
 	UpdatedAt  time.Time  `json:"-"`
 	DeletedAt  *time.Time `json:"-"`
-	partyID    uint
-	roundID    uint
-	area       area `gorm:"foreignkey:AreaRefer"`
-	name       string
-	candidates []candidate
-	votes      []vote
+	PartyID    uint
+	RoundID    uint
+	Area       Area `gorm:"foreignkey:AreaRefer"`
+	Name       string
+	Candidates []Candidate
+	Votes      []Vote
 }
 
-type candidate struct {
+// Candidate
+type Candidate struct {
 	ID                       uint       `gorm:"primary_key"`
 	CreatedAt                time.Time  `json:"-"`
 	UpdatedAt                time.Time  `json:"-"`
 	DeletedAt                *time.Time `json:"-"`
-	candidateListID          uint
-	fullName                 string
-	rank                     uint
-	communityCounseller      bool
-	birthdate                time.Time
-	potentialIncompatibility bool
-	refused                  bool
-	removed                  bool
-}
-
-type vote struct {
-	deskRoundID     uint       `gorm:"primary_key"`
-	candidateListID uint       `gorm:"primary_key"`
+	CandidateListID          uint
+	FullName                 string
+	Rank                     uint
+	CommunityCounseller      bool
+	Birthdate                time.Time
+	PotentialIncompatibility bool
+	Refused                  bool
+	Removed                  bool
+}
+
+// Vote
+type Vote struct {
+	DeskRoundID     uint       `gorm:"primary_key"`
+	CandidateListID uint       `gorm:"primary_key"`
 	CreatedAt       time.Time  `json:"-"`
 	UpdatedAt       time.Time  `json:"-"`
 	DeletedAt       *time.Time `json:"-"`
-	voiceNumber     uint
-	blank           bool
-	null            bool
+	VoiceNumber     uint
+	Blank           bool
+	Null            bool
 }
 
 // NewDataHandler init a DataHandler and returns a pointer to it
@@ -180,18 +195,18 @@ func NewDataHandler() *DataHandler {
 	db.LogMode(true)
 
 	// Migrate the schema
-	db.AutoMigrate(&capturer{})
-	db.AutoMigrate(&election{})
-	db.AutoMigrate(&area{})
-	db.AutoMigrate(&section{})
-	db.AutoMigrate(&desk{})
-	db.AutoMigrate(&round{})
-	db.AutoMigrate(&deskRound{})
-	db.AutoMigrate(&party{})
-	db.AutoMigrate(&candidateList{})
-	db.AutoMigrate(&candidate{})
-	db.AutoMigrate(&vote{})
-	db.AutoMigrate(&parameter{})
+	db.AutoMigrate(&Capturer{})
+	db.AutoMigrate(&Election{})
+	db.AutoMigrate(&Area{})
+	db.AutoMigrate(&Section{})
+	db.AutoMigrate(&Desk{})
+	db.AutoMigrate(&Round{})
+	db.AutoMigrate(&DeskRound{})
+	db.AutoMigrate(&Party{})
+	db.AutoMigrate(&CandidateList{})
+	db.AutoMigrate(&Candidate{})
+	db.AutoMigrate(&Vote{})
+	db.AutoMigrate(&Parameter{})
 	return &DataHandler{db: db}
 }
 
@@ -199,32 +214,24 @@ func NewDataHandler() *DataHandler {
 func (d *DataHandler) ProcessAPI(w http.ResponseWriter, r *http.Request) {
 	api := strings.Split(strings.TrimPrefix(r.URL.Path, "/api/"), "/")[0]
 	switch api {
+	case "Capturer":
+		d.HandleCapturer(w, r)
 	}
 
 }
 
 func (d *DataHandler) getLoggedUser(w http.ResponseWriter, r *http.Request) interface{} {
-	// user := auth.GetLoggedUserTechnical(w, r)
-	// if user.Role != "" && (user.Role == "BANKER") {
-	// 	var o UserBanker
-	// 	if err := d.db.Where(reqUserID, user.ID).First(&o).Error; err != nil {
-	// 		o := UserBanker{UserID: user.ID, Name: user.Login}
-	// 		d.db.Create(&o)
-	// 		d.db.Where(reqUserID, user.ID).First(&o)
-	// 		return o
-	// 	}
-	// 	return o
-	// } else if user.Role != "" && (user.Role == "CLIENT") {
-	// 	var o UserClient
-	// 	if err := d.db.Where(reqUserID, user.ID).First(&o).Error; err != nil {
-	// 		o := UserClient{UserID: user.ID, Name: user.Login}
-	// 		d.db.Create(&o)
-	// 		d.db.Where(reqUserID, user.ID).First(&o)
-	// 		return o
-	// 	}
-
-	// 	return o
-	// }
+	user := auth.GetLoggedUserTechnical(w, r)
+	if user.Role != "" && (user.Role == "CAPTURER") {
+		var o Capturer
+		if err := d.db.Where("user_id = ?", user.ID).First(&o).Error; err != nil {
+			o := Capturer{UserID: user.ID, Name: user.Login}
+			d.db.Create(&o)
+			d.db.First(&o, user.ID)
+			return o
+		}
+		return o
+	}
 
 	return nil
 }
diff --git a/internal/rootmux/admin_test.go b/internal/rootmux/admin_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ba9dc3b2045ff080574b25098862fc99febdc263
--- /dev/null
+++ b/internal/rootmux/admin_test.go
@@ -0,0 +1,42 @@
+package rootmux
+
+import (
+	"encoding/json"
+	"testing"
+
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
+	"forge.grandlyon.com/apoyen/sdk-go/pkg/tester"
+)
+
+/**
+Banker TESTS (those tests are to check the bankers rights)
+**/
+func AdminTests(t *testing.T) {
+	// Create the tester
+	ts, do, _ := createTester(t)
+	defer ts.Close() // Close the tester
+	tests := func() {
+		// Get the XSRF Token
+		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
+		token := auth.TokenData{}
+		json.Unmarshal([]byte(response), &token)
+		xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+
+		// Create a capturer
+		do("POST", "/api/Capturer", xsrfHeader, `{"UserID":1,"Name":"Capturer"}`, 200, `{"ID":3,"UserID":1,"Name":"Capturer","DeskRounds":null}`)
+		// Get the capturer
+		do("GET", "/api/Capturer/1", xsrfHeader, ``, 200, `{"ID":1,"UserID":2,"Name":"Capturer","DeskRounds":[]}`)
+		// Get all the capturer
+		do("GET", "/api/Capturer/", xsrfHeader, ``, 200, `[{"ID":1,"UserID":2,"Name":"Capturer","DeskRounds":[]},{"ID":2,"UserID":3,"Name":"Capturer","DeskRounds":[]},{"ID":3,"UserID":1,"Name":"Capturer","DeskRounds":[]}]`)
+		// Update a capturer
+		do("PUT", "/api/Capturer/1", xsrfHeader, `{"ID":1,"UserID":2,"Name":"capturer"}`, 200, `{"ID":1,"UserID":2,"Name":"capturer","DeskRounds":[]}`)
+		// Delete a capturer
+		do("DELETE", "/api/Capturer/3", xsrfHeader, ``, 200, ``)
+
+	}
+	// Do a in memory login with an known admin
+	do("POST", "/Login", noH, `{"login": "admin","password": "password"}`, 200, "")
+	tests()
+	// Try to logout (must pass)
+	do("GET", "/Logout", noH, "", 200, "Logout OK")
+}
diff --git a/internal/rootmux/capturer_test.go b/internal/rootmux/capturer_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..741c7a8a269c7540b783024d381255a7d4d29b4a
--- /dev/null
+++ b/internal/rootmux/capturer_test.go
@@ -0,0 +1,44 @@
+package rootmux
+
+import (
+	"encoding/json"
+	"testing"
+
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
+	"forge.grandlyon.com/apoyen/sdk-go/pkg/tester"
+)
+
+/**
+Banker TESTS (those tests are to check the bankers rights)
+**/
+func CapturerTests(t *testing.T) {
+	// Create the tester
+	ts, do, _ := createTester(t)
+	defer ts.Close() // Close the tester
+	tests := func() {
+		// Get the XSRF Token
+		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
+		token := auth.TokenData{}
+		json.Unmarshal([]byte(response), &token)
+		xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+
+		// Create a capturer should fail with 405
+		do("POST", "/api/Capturer", xsrfHeader, `{"userID":2,"name":"Capturer"}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Get the capturer connected
+		do("GET", "/api/Capturer/1", xsrfHeader, "", 200, `{"ID":1,"UserID":2,"Name":"Capturer","DeskRounds":[]}`)
+		// Get another capturer should fail with 405
+		do("GET", "/api/Capturer/2", xsrfHeader, "", 403, `You can not access this ressource`)
+		// Get all the capturer return only the capturer connected
+		do("GET", "/api/Capturer/", xsrfHeader, "", 200, `[{"ID":1,"UserID":2,"Name":"Capturer","DeskRounds":[]}]`)
+		// Update a capturer should fail with 405
+		do("PUT", "/api/Capturer/1", xsrfHeader, `{"ID":1,"UserID":2,"Name":"capturer"}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Delete a capturer should fail with 405
+		do("DELETE", "/api/Capturer/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
+
+	}
+	// Do a in memory login with an known admin
+	do("POST", "/Login", noH, `{"login": "capturer","password": "password"}`, 200, "")
+	tests()
+	// Try to logout (must pass)
+	do("GET", "/Logout", noH, "", 200, "Logout OK")
+}
diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go
index 396912e5d990dfba9e7dd73bcd16fcaa232c1e92..62facc32e65584f1cbab90017866450e88ff90a4 100644
--- a/internal/rootmux/rootmux_test.go
+++ b/internal/rootmux/rootmux_test.go
@@ -55,6 +55,12 @@ func TestAll(t *testing.T) {
 
 	resetData(t)
 	appTests(t)
+	resetData(t)
+	AdminTests(t)
+	resetData(t)
+	CapturerTests(t)
+	resetData(t)
+	VisualizerTests(t)
 
 	os.RemoveAll("./data")
 }
@@ -79,8 +85,9 @@ func appTests(t *testing.T) {
 		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
 		token := auth.TokenData{}
 		json.Unmarshal([]byte(response), &token)
-		// xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+		xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
 
+		do("POST", "/api/Capturer", xsrfHeader, `{"UserID":2,"Name":"Capturer"}`, 500, `UserID is already bind to a Capturer`)
 	}
 	// Do an OAuth2 login with an known admin
 	do("GET", "/OAuth2Login", noH, "", 200, "<!DOCTYPE html>")
@@ -104,8 +111,11 @@ func resetData(t *testing.T) {
 		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
 		token := auth.TokenData{}
 		json.Unmarshal([]byte(response), &token)
-		// xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+		xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
 
+		// Create a capturer
+		do("POST", "/api/Capturer", xsrfHeader, `{"UserID":2,"Name":"Capturer"}`, 200, `{"ID":1,"UserID":2,"Name":"Capturer","DeskRounds":null}`)
+		do("POST", "/api/Capturer", xsrfHeader, `{"UserID":3,"Name":"Capturer"}`, 200, `{"ID":2,"UserID":3,"Name":"Capturer","DeskRounds":null}`)
 	}
 	do("POST", "/Login", noH, `{"login": "admin","password": "password"}`, 200, "")
 	init()
diff --git a/internal/rootmux/visualizer_test.go b/internal/rootmux/visualizer_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8a8b94909a0f9481bcc048f041e7ab12787cb46f
--- /dev/null
+++ b/internal/rootmux/visualizer_test.go
@@ -0,0 +1,42 @@
+package rootmux
+
+import (
+	"encoding/json"
+	"testing"
+
+	"forge.grandlyon.com/apoyen/elections/internal/auth"
+	"forge.grandlyon.com/apoyen/sdk-go/pkg/tester"
+)
+
+/**
+Banker TESTS (those tests are to check the bankers rights)
+**/
+func VisualizerTests(t *testing.T) {
+	// Create the tester
+	ts, do, _ := createTester(t)
+	defer ts.Close() // Close the tester
+	tests := func() {
+		// Get the XSRF Token
+		response := do("GET", "/api/common/WhoAmI", noH, "", 200, "")
+		token := auth.TokenData{}
+		json.Unmarshal([]byte(response), &token)
+		xsrfHeader := tester.Header{Key: "XSRF-TOKEN", Value: token.XSRFToken}
+
+		// Create a capturer should fail with 405
+		do("POST", "/api/Capturer", xsrfHeader, `{"userID":2,"name":"Capturer"}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Get a capturer should fail with 405
+		do("GET", "/api/Capturer/1", xsrfHeader, "", 405, `You're not authorize to execute this method on this ressource.`)
+		// Get all the capturer should fail with 405
+		do("GET", "/api/Capturer/", xsrfHeader, "", 405, `You're not authorize to execute this method on this ressource.`)
+		// Update a capturer should fail with 405
+		do("PUT", "/api/Capturer/1", xsrfHeader, `{"ID":1,"UserID":2,"Name":"capturer"}`, 405, `You're not authorize to execute this method on this ressource.`)
+		// Delete a capturer should fail with 405
+		do("DELETE", "/api/Capturer/1", xsrfHeader, ``, 405, `You're not authorize to execute this method on this ressource.`)
+
+	}
+	// Do a in memory login with an known admin
+	do("POST", "/Login", noH, `{"login": "visualizer","password": "password"}`, 200, "")
+	tests()
+	// Try to logout (must pass)
+	do("GET", "/Logout", noH, "", 200, "Logout OK")
+}