Browse Source

Implemented httpheader userid handler.

pull/28/head
Simon Eisenmann 11 years ago
parent
commit
bec399dca3
  1. 17
      server.conf.in
  2. 2
      src/app/spreed-speakfreely-server/sessions.go
  3. 36
      src/app/spreed-speakfreely-server/users.go

17
server.conf.in

@ -98,14 +98,23 @@ sessionSecret = the-default-secret-do-not-keep-me @@ -98,14 +98,23 @@ sessionSecret = the-default-secret-do-not-keep-me
[users]
; Set to true to enable user functionality.
enabled = false
; Set authorization mode for users. Currently implemented is the "sharedsecret"
; mode which does validate the userid with a HMAC authentication secret.
; The format goes like this:
; BASE64(HMAC-SHA-256(secret, expirationTimestampInSeconds:userid))
; Set users authorization mode.
; sharedsecret:
; Validates the userid with a HMAC authentication secret.
; The format goes like this:
; BASE64(HMAC-SHA-256(secret, expirationTimestampInSeconds:userid))
; httpheader:
; The userid is provided as an HTTP header. The server does not do any
; validation. This usually only makes sense with a front end HTTPS proxy which
; does the authentication and injects the user id as HTTP header for sessions
; REST requests. In mode httpheader, allowRegistration should be false.
;mode = sharedsecret
; The shared secred for HMAC validation in "sharedsecret" mode. Best use 32 or
; 64 bytes of random data.
;sharedsecret_secret = some-secret-do-not-keep
; The HTTP header name where to find the userid in "httpheader" mode.
;httpheader_header = x-userid
; The server can create new userids if enabled. Set allowRegistration to true to
; enable userid creation/registration. Users are created to match the settings
; of the currently configured mode (see above).

2
src/app/spreed-speakfreely-server/sessions.go

@ -84,7 +84,7 @@ func (sessions *Sessions) Patch(request *http.Request) (int, interface{}, http.H @@ -84,7 +84,7 @@ func (sessions *Sessions) Patch(request *http.Request) (int, interface{}, http.H
}
// Validate with users handler.
userid, err := sessions.users.handler.Validate(&snr)
userid, err := sessions.users.handler.Validate(&snr, request)
if err != nil {
error = true
log.Println("Session patch failed - users validation failed.", err)

36
src/app/spreed-speakfreely-server/users.go

@ -38,8 +38,8 @@ import ( @@ -38,8 +38,8 @@ import (
)
type UsersHandler interface {
Validate(snr *SessionNonceRequest) (string, error)
Create(snr *UserNonce) (*UserNonce, error)
Validate(snr *SessionNonceRequest, request *http.Request) (string, error)
Create(snr *UserNonce, request *http.Request) (*UserNonce, error)
}
type UsersSharedsecretHandler struct {
@ -54,7 +54,7 @@ func (uh *UsersSharedsecretHandler) createHMAC(useridCombo string) string { @@ -54,7 +54,7 @@ func (uh *UsersSharedsecretHandler) createHMAC(useridCombo string) string {
}
func (uh *UsersSharedsecretHandler) Validate(snr *SessionNonceRequest) (string, error) {
func (uh *UsersSharedsecretHandler) Validate(snr *SessionNonceRequest, request *http.Request) (string, error) {
// Parse UseridCombo.
useridCombo := strings.SplitN(snr.UseridCombo, ":", 2)
@ -79,7 +79,7 @@ func (uh *UsersSharedsecretHandler) Validate(snr *SessionNonceRequest) (string, @@ -79,7 +79,7 @@ func (uh *UsersSharedsecretHandler) Validate(snr *SessionNonceRequest) (string,
}
func (uh *UsersSharedsecretHandler) Create(un *UserNonce) (*UserNonce, error) {
func (uh *UsersSharedsecretHandler) Create(un *UserNonce, request *http.Request) (*UserNonce, error) {
// TODO(longsleep): Make this configureable - One year for now ...
expiration := time.Now().Add(time.Duration(1) * time.Hour * 24 * 31 * 12)
@ -91,6 +91,26 @@ func (uh *UsersSharedsecretHandler) Create(un *UserNonce) (*UserNonce, error) { @@ -91,6 +91,26 @@ func (uh *UsersSharedsecretHandler) Create(un *UserNonce) (*UserNonce, error) {
}
type UsersHTTPHeaderHandler struct {
headerName string
}
func (uh *UsersHTTPHeaderHandler) Validate(snr *SessionNonceRequest, request *http.Request) (string, error) {
userid := request.Header.Get(uh.headerName)
if userid == "" {
return "", errors.New("no userid provided")
}
return userid, nil
}
func (uh *UsersHTTPHeaderHandler) Create(un *UserNonce, request *http.Request) (*UserNonce, error) {
return nil, errors.New("create is not possible in httpheader mode")
}
type UserNonce struct {
Nonce string `json:"nonce"`
Userid string `json:"userid"`
@ -117,6 +137,12 @@ func NewUsers(hub *Hub, realm string, runtime phoenix.Runtime) *Users { @@ -117,6 +137,12 @@ func NewUsers(hub *Hub, realm string, runtime phoenix.Runtime) *Users {
if secret != "" {
handler = &UsersSharedsecretHandler{secret: []byte(secret)}
}
case "httpheader":
headerName, _ := runtime.GetString("users", "httpheader_header")
if headerName == "" {
headerName = "x-users"
}
handler = &UsersHTTPHeaderHandler{headerName: headerName}
default:
mode = ""
}
@ -163,7 +189,7 @@ func (users *Users) Post(request *http.Request) (int, interface{}, http.Header) @@ -163,7 +189,7 @@ func (users *Users) Post(request *http.Request) (int, interface{}, http.Header)
return 400, NewApiError("users_request_failed", fmt.Sprintf("Error: %q", err)), http.Header{"Content-Type": {"application/json"}}
}
un, err := users.handler.Create(&UserNonce{Nonce: nonce, Userid: userid, Success: true})
un, err := users.handler.Create(&UserNonce{Nonce: nonce, Userid: userid, Success: true}, request)
if err != nil {
return 400, NewApiError("users_create_failed", fmt.Sprintf("Error: %q", err)), http.Header{"Content-Type": {"application/json"}}
}

Loading…
Cancel
Save