Working auth system
parent
b0f4eb069e
commit
6a692fdf5f
@ -1,41 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
// AuthService rappresenta un servizio di autenticazione
|
|
||||||
// type AuthService interface {
|
|
||||||
// GetUsers() []User
|
|
||||||
|
|
||||||
// GetUser(username string) User
|
|
||||||
|
|
||||||
// // LoginUser if successful returns the token for this user that will be stored in an HTTP cookie.
|
|
||||||
// LoginUser(username, password string) (string, error)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// LdapService ...
|
|
||||||
type LdapService struct {
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
// FakeService ...
|
|
||||||
type FakeService struct {
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAuthenticationService crea un nuovo servizio di autenticazione e controlla se è attivo
|
|
||||||
// func NewAuthenticationService(url string) (*LdapService, error) {
|
|
||||||
// service := new(LdapService)
|
|
||||||
// service.URL = url
|
|
||||||
|
|
||||||
// res, err := service.Get("status")
|
|
||||||
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// status, _ := ioutil.ReadAll(res.Body)
|
|
||||||
|
|
||||||
// if string(status) != "true" {
|
|
||||||
// log.Fatalf("Authentication service isn't online, status: '%s'", status)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return service, nil
|
|
||||||
// }
|
|
@ -0,0 +1,42 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
type User interface {
|
||||||
|
GetUsername() string
|
||||||
|
GetName() string
|
||||||
|
GetSurname() string
|
||||||
|
GetFullName() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Session interface {
|
||||||
|
GetUsername() string
|
||||||
|
GetToken() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthenticatorService interface {
|
||||||
|
GetUser(username string) (User, error)
|
||||||
|
GetUsers() ([]User, error)
|
||||||
|
GetSession(token string) (Session, error)
|
||||||
|
Login(username, password string) (Session, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UserForSession(as AuthenticatorService, token string) (User, error) {
|
||||||
|
session, err := as.GetSession(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := as.GetUser(session.GetUsername())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(host string) AuthenticatorService {
|
||||||
|
if host == ":memory:" {
|
||||||
|
return exampleMemoryUsers
|
||||||
|
}
|
||||||
|
|
||||||
|
return &LDAPAuthService{host}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LDAPUser struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
NumericId int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Surname string `json:"surname"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
Gecos string `json:"gecos"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u LDAPUser) GetUsername() string {
|
||||||
|
return u.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u LDAPUser) GetName() string {
|
||||||
|
return u.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u LDAPUser) GetSurname() string {
|
||||||
|
return u.Surname
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u LDAPUser) GetFullName() string {
|
||||||
|
return u.Gecos
|
||||||
|
}
|
||||||
|
|
||||||
|
type SimpleSession struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
CreatedOn time.Time `json:"createdOn"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SimpleSession) GetUsername() string {
|
||||||
|
return s.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SimpleSession) GetToken() string {
|
||||||
|
return s.Token
|
||||||
|
}
|
||||||
|
|
||||||
|
type LDAPAuthService struct {
|
||||||
|
Host string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *LDAPAuthService) doGetRequest(url string, response interface{}) error {
|
||||||
|
req, err := http.NewRequest(
|
||||||
|
"GET", path.Join(a.Host, "ldap", url), bytes.NewBuffer([]byte("")),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.NewDecoder(res.Body).Decode(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *LDAPAuthService) doPostRequest(url string, request interface{}, response interface{}) error {
|
||||||
|
jsonStr, err := json.Marshal(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", path.Join(a.Host, "ldap", url), bytes.NewBuffer(jsonStr))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.NewDecoder(res.Body).Decode(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *LDAPAuthService) GetUser(username string) (User, error) {
|
||||||
|
var user LDAPUser
|
||||||
|
if err := a.doGetRequest(fmt.Sprintf("/user/%s", username), &user); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *LDAPAuthService) GetUsers() ([]User, error) {
|
||||||
|
ldapUsers := []*LDAPUser{}
|
||||||
|
if err := a.doGetRequest(fmt.Sprintf("/users"), &ldapUsers); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
users := make([]User, len(ldapUsers))
|
||||||
|
for i, u := range ldapUsers {
|
||||||
|
users[i] = u
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *LDAPAuthService) GetSession(token string) (Session, error) {
|
||||||
|
var response SimpleSession
|
||||||
|
if err := a.doGetRequest(fmt.Sprintf("/session/%s", token), &response); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *LDAPAuthService) Login(username, password string) (Session, error) {
|
||||||
|
body := map[string]interface{}{
|
||||||
|
"username": username,
|
||||||
|
"password": password,
|
||||||
|
}
|
||||||
|
|
||||||
|
var response SimpleSession
|
||||||
|
if err := a.doPostRequest(fmt.Sprintf("/login"), body, &response); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.phc.dm.unipi.it/phc/website/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
var exampleMemoryUsers = &Memory{
|
||||||
|
Users: map[string]*MemoryUser{
|
||||||
|
"aziis98": {
|
||||||
|
Username: "aziis98",
|
||||||
|
Name: "Antonio",
|
||||||
|
Surname: "De Lucreziis",
|
||||||
|
Password: "123",
|
||||||
|
},
|
||||||
|
"bachoseven": {
|
||||||
|
Username: "bachoseven",
|
||||||
|
Name: "Francesco",
|
||||||
|
Surname: "Minnocci",
|
||||||
|
Password: "234",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Sessions: map[string]*MemorySession{},
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemoryUser struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Surname string `json:"surname"`
|
||||||
|
|
||||||
|
Password string `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MemoryUser) GetUsername() string {
|
||||||
|
return u.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MemoryUser) GetName() string {
|
||||||
|
return u.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MemoryUser) GetSurname() string {
|
||||||
|
return u.Surname
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MemoryUser) GetFullName() string {
|
||||||
|
return u.Name + " " + u.Surname
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemorySession struct {
|
||||||
|
Username string
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MemorySession) GetUsername() string {
|
||||||
|
return s.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MemorySession) GetToken() string {
|
||||||
|
return s.Token
|
||||||
|
}
|
||||||
|
|
||||||
|
type Memory struct {
|
||||||
|
Users map[string]*MemoryUser
|
||||||
|
Sessions map[string]*MemorySession
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Memory) GetUser(username string) (User, error) {
|
||||||
|
user, ok := m.Users[username]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf(`no user with that username`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Memory) GetUsers() ([]User, error) {
|
||||||
|
users := make([]User, len(m.Users))
|
||||||
|
i := 0
|
||||||
|
for _, u := range m.Users {
|
||||||
|
users[i] = u
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Memory) GetSession(token string) (Session, error) {
|
||||||
|
session, ok := m.Sessions[token]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf(`invalid session token`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return session, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Memory) Login(username string, password string) (Session, error) {
|
||||||
|
user, err := m.GetUser(username)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
memUser := user.(*MemoryUser)
|
||||||
|
|
||||||
|
if memUser.Password != password {
|
||||||
|
return nil, fmt.Errorf(`invalid credentials`)
|
||||||
|
}
|
||||||
|
|
||||||
|
session := &MemorySession{username, util.GenerateRandomString(15)}
|
||||||
|
m.Sessions[session.Token] = session
|
||||||
|
|
||||||
|
return session, nil
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package util
|
@ -0,0 +1,18 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateRandomString(n int) string {
|
||||||
|
b := make([]byte, n)
|
||||||
|
|
||||||
|
_, err := rand.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64.URLEncoding.EncodeToString(b)
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
{{template "base" .}}
|
||||||
|
|
||||||
|
{{define "title"}}Profilo @{{ .User.Username }} • PHC{{end}}
|
||||||
|
|
||||||
|
{{define "body"}}
|
||||||
|
<section>
|
||||||
|
<h1>Profilo di @{{ .User.Username }}</h1>
|
||||||
|
<h2>Impostazioni</h2>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae earum amet delectus cumque obcaecati minus quos aliquid fugiat reprehenderit voluptatum?
|
||||||
|
</p>
|
||||||
|
<h2>Recupero Credenziali Poisson</h2>
|
||||||
|
<p>
|
||||||
|
Per il recupero credenziali vieni direttamente al PHC a parlarne con calma con noi altrimenti puoi inviaci una email all'indirizzo <a href="mailto:{{ .Config.Email }}">{{ .Config.Email }}</a> e poi recuperare le nuove credenziali sul sito <a href="https://credenziali.phc.dm.unipi.it/">credenziali.phc.dm.unipi.it</a>.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
{{end}}
|
Loading…
Reference in New Issue