github.com/apremalal/vamps-core@v1.0.1-0.20161221121535-d430b56ec174/controllers/authentication_controller.go (about)

     1  package controllers
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  	"strconv"
     7  
     8  	log "github.com/Sirupsen/logrus"
     9  	jwt "github.com/dgrijalva/jwt-go"
    10  	"github.com/vedicsoft/vamps-core/commons"
    11  	"github.com/vedicsoft/vamps-core/models"
    12  )
    13  
    14  type TokenAuthentication struct {
    15  	Token    string `json:"token" form:"token"`
    16  	TenantId int64  `json:"tenantid" form:"tenantid"`
    17  }
    18  
    19  func Login(requestUser *models.SystemUser) (int, []byte, error) {
    20  	authEngine := InitJWTAuthenticationEngine()
    21  	requestUser.TenantId = getTenantId(requestUser)
    22  	if authEngine.Authenticate(requestUser) {
    23  		token, err := authEngine.GenerateToken(requestUser)
    24  		if err != nil {
    25  			return http.StatusInternalServerError, []byte(""), err
    26  		} else {
    27  			response, _ := json.Marshal(TokenAuthentication{token, requestUser.TenantId})
    28  			return http.StatusOK, response, nil
    29  		}
    30  	}
    31  	return http.StatusUnauthorized, []byte(""), nil
    32  }
    33  
    34  func RefreshToken(requestUser *models.SystemUser) []byte {
    35  	authEngine := InitJWTAuthenticationEngine()
    36  	token, err := authEngine.GenerateToken(requestUser)
    37  	if err != nil {
    38  		panic(err)
    39  	}
    40  	requestUser.TenantId = getTenantId(requestUser)
    41  	response, err := json.Marshal(TokenAuthentication{token, requestUser.TenantId})
    42  	if err != nil {
    43  		panic(err)
    44  	}
    45  	return response
    46  }
    47  
    48  func Logout(req *http.Request) error {
    49  	authEngine := InitJWTAuthenticationEngine()
    50  	tokenRequest, err := jwt.ParseFromRequest(req, func(token *jwt.Token) (interface{}, error) {
    51  		return authEngine.PublicKey, nil
    52  	})
    53  	if err != nil {
    54  		return err
    55  	}
    56  	tokenString := req.Header.Get("Authorization")
    57  	return authEngine.Logout(tokenString, tokenRequest)
    58  }
    59  
    60  func RequireTokenAuthentication(inner http.Handler) http.Handler {
    61  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    62  		authBackend := InitJWTAuthenticationEngine()
    63  		token, err := jwt.ParseFromRequest(
    64  			r,
    65  			func(token *jwt.Token) (interface{}, error) {
    66  				return authBackend.PublicKey, nil
    67  			})
    68  		if err != nil || !token.Valid || authBackend.IsInBlacklist(r.Header.Get("Authorization")) {
    69  			log.Debug("Authentication failed " + err.Error())
    70  			w.WriteHeader(http.StatusForbidden)
    71  			return
    72  		} else {
    73  			sClaims, _ := json.Marshal(token.Claims["scopes"])
    74  			r.Header.Set("scopes", string(sClaims))
    75  			r.Header.Set("username", token.Claims["sub"].(string))
    76  			r.Header.Set("userid", strconv.FormatFloat((token.Claims["userid"]).(float64), 'f', 0, 64))
    77  			r.Header.Set("tenantid", strconv.FormatFloat((token.Claims["tenantid"]).(float64), 'f', 0, 64))
    78  		}
    79  		inner.ServeHTTP(w, r)
    80  	})
    81  }
    82  
    83  func RequireTokenAuthenticationAndAuthorization(inner http.Handler) http.Handler {
    84  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    85  		authBackend := InitJWTAuthenticationEngine()
    86  		token, err := jwt.ParseFromRequest(
    87  			r,
    88  			func(token *jwt.Token) (interface{}, error) {
    89  				return authBackend.PublicKey, nil
    90  			})
    91  		if err != nil || !token.Valid || authBackend.IsInBlacklist(r.Header.Get("Authorization")) {
    92  			log.Debug("Authentication failed " + err.Error())
    93  			w.WriteHeader(http.StatusForbidden)
    94  			return
    95  		} else {
    96  			sClaims, _ := json.Marshal(token.Claims["scopes"])
    97  			userID := token.Claims["userid"]
    98  			tenantID := token.Claims["tenantid"]
    99  			r.Header.Set("scopes", string(sClaims))
   100  			r.Header.Set("username", token.Claims["sub"].(string))
   101  			r.Header.Set("userid", strconv.FormatFloat(userID.(float64), 'f', 0, 64))
   102  			r.Header.Set("tenantid", strconv.FormatFloat(tenantID.(float64), 'f', 0, 64))
   103  			a, err := isAuthorized2(int(tenantID.(float64)), int(userID.(float64)), r)
   104  			if err != nil {
   105  				log.Debug("authorization failed due to error " + err.Error())
   106  				w.WriteHeader(http.StatusUnauthorized)
   107  				return
   108  			}
   109  			if !a {
   110  				log.Debug("authorization failed for user " + strconv.Itoa(int(userID.(float64))))
   111  				w.WriteHeader(http.StatusUnauthorized)
   112  				return
   113  			}
   114  		}
   115  		inner.ServeHTTP(w, r)
   116  	})
   117  }
   118  
   119  func getTenantId(user *models.SystemUser) int64 {
   120  	dbMap := commons.GetDBConnection(commons.USER_STORE_DB)
   121  	tenantId, err := dbMap.SelectInt("SELECT tenantid FROM vs_tenants WHERE domain=?", user.TenantDomain)
   122  	checkErr(err, "Select failed")
   123  	return tenantId
   124  }
   125  
   126  func checkErr(err error, msg string) {
   127  	if err != nil {
   128  		log.Error(msg, err)
   129  	}
   130  }