initialize authenticators under logical names, if so configured

This commit is contained in:
or-else
2018-12-26 15:26:18 +03:00
parent dfe3c23e75
commit 0249cf9fba
9 changed files with 49 additions and 25 deletions

View File

@ -1,8 +1,5 @@
#!/bin/bash
# Remove the old config.
rm -f working.config
# If EXT_CONFIG is set, use it as a config file.
if [ ! -z "$EXT_CONFIG" ] ; then
CONFIG="$EXT_CONFIG"
@ -15,6 +12,9 @@ if [ ! -z "$EXT_CONFIG" ] ; then
else
CONFIG=working.config
# Remove the old config.
rm -f working.config
# Enable email verification if $SMTP_SERVER is defined.
if [ ! -z "$SMTP_SERVER" ] ; then
EMAIL_VERIFICATION_REQUIRED='"auth"'

View File

@ -1,7 +1,7 @@
# Frequently Asked Questions
### Q: I'm running Tinode server in a docker container. Where can I find server logs?<br/>
### Q: Where can I find server logs when running in Docker?<br/>
**A**: The log is in the container at `/var/log/tinode.log`. Attach to a running container with command
```
docker exec -it name-of-the-running-container /bin/bash
@ -34,7 +34,7 @@ If you are using the official [Docker image](https://hub.docker.com/u/tinode):
### Q: How to create a `root` user?<br/>
**A**: The `root` access can be granted to a user only by executing a database query. First create or choose the use you want to promote to `root` then execute the query:
**A**: The `root` access can be granted to a user only by executing a database query. First create or choose the user you want to promote to `root` then execute the query:
* RethinkDB:
```js
r.db("tinode").table("auth").get("basic:login-of-the-user-to-make-root").update({authLvl: 30})

View File

@ -15,7 +15,7 @@ import (
type authenticator struct{}
// Init is a noop, always returns success.
func (authenticator) Init(unused string) error {
func (authenticator) Init(_, _ string) error {
return nil
}
@ -33,7 +33,7 @@ func (authenticator) UpdateRecord(rec *auth.Rec, secret []byte) error {
return nil
}
// Authenticate is not supported. It's used only at account creation time.
// Authenticate is not supported. This authenticator is used only at account creation time.
func (authenticator) Authenticate(secret []byte) (*auth.Rec, []byte, error) {
return nil, nil, types.ErrUnsupported
}

View File

@ -43,6 +43,10 @@ func parseSecret(bsecret []byte) (uname, password string, err error) {
// Init initializes the basic authenticator.
func (a *authenticator) Init(jsonconf, name string) error {
if a.name != "" {
return errors.New("auth_basic: already initialized as " + a.name + "; " + name)
}
type configType struct {
// AddToTags indicates that the user name should be used as a searchable tag.
AddToTags bool `json:"add_to_tags"`
@ -171,7 +175,7 @@ func (a *authenticator) Authenticate(secret []byte) (*auth.Rec, []byte, error) {
}
// IsUnique checks login uniqueness.
func (authenticator) IsUnique(secret []byte) (bool, error) {
func (a *authenticator) IsUnique(secret []byte) (bool, error) {
uname, _, err := parseSecret(secret)
if err != nil {
return false, err

View File

@ -64,6 +64,10 @@ type response struct {
// Init initializes the handler.
func (a *authenticator) Init(jsonconf, name string) error {
if a.name != "" {
return errors.New("auth_rest: already initialized as " + a.name + "; " + name)
}
type configType struct {
// ServerUrl is the URL of the server to call.
ServerUrl string `json:"server_url"`

View File

@ -44,8 +44,8 @@ type tokenLayout struct {
// Init initializes the authenticator: parses the config and sets salt, serial number and lifetime.
func (ta *authenticator) Init(jsonconf, name string) error {
if ta.hmacSalt != nil {
return errors.New("auth_token: already initialized")
if ta.name != "" {
return errors.New("auth_token: already initialized as " + ta.name + "; " + name)
}
type configType struct {

View File

@ -287,11 +287,12 @@ func main() {
log.Fatal(err)
}
for name, jsconf := range config.Auth {
if name != "logical_names" {
if authhdl := store.GetAuthHandler(name); authhdl == nil {
log.Fatal("Config provided for unknown authentication scheme '" + name + "'")
} else if err := authhdl.Init(string(jsconf)); err != nil {
authNames := store.GetAuthNames()
for _, name := range authNames {
if authhdl := store.GetLogicalAuthHandler(name); authhdl == nil {
log.Fatalln("Unknown authenticator", name)
} else if jsconf := config.Auth[name]; jsconf != nil {
if err := authhdl.Init(string(jsconf), name); err != nil {
log.Fatalln("Failed to init auth scheme", name+":", err)
}
}

View File

@ -608,21 +608,35 @@ func RegisterAuthScheme(name string, handler auth.AuthHandler) {
authHandlers[name] = handler
}
// GetAuthHandler returns an auth handler by actual hardcoded name irrspectful of logical naming.
func GetAuthHandler(name string) auth.AuthHandler {
return authHandlers[strings.ToLower(name)]
}
// GetAuthHandlerNames returns a slice of strings containing authenticator names.
func GetAuthHandlerNames() []string {
// GetAuthNames returns all addressable auth handler names, logical and hardcoded
// excluding those which are disabled like "basic:".
func GetAuthNames() []string {
if len(authHandlers) == 0 {
return nil
}
var names []string
var allNames []string
for name, _ := range authHandlers {
names = append(names, name)
allNames = append(allNames, name)
}
for name, _ := range authHandlerNames {
allNames = append(allNames, name)
}
var names []string
for _, name := range allNames {
if GetLogicalAuthHandler(name) != nil {
names = append(names, name)
}
}
return names
}
// GetAuthHandler returns an auth handler by actual hardcoded name irrspectful of logical naming.
func GetAuthHandler(name string) auth.AuthHandler {
return authHandlers[strings.ToLower(name)]
}
// GetLogicalAuthHandler returns an auth handler by logical name. If there is no handler by that
@ -659,6 +673,7 @@ func InitAuthLogicalNames(config json.RawMessage) error {
if parts[0] == "" {
return errors.New("store: empty logical auth name '" + pair + "'")
}
parts[0] = strings.ToLower(parts[0])
if _, ok := authHandlerNames[parts[0]]; ok {
return errors.New("store: duplicate mapping for logical auth name '" + pair + "'")
}

View File

@ -279,7 +279,7 @@ func replyDelUser(s *Session, msg *ClientComMessage) {
if reply == nil {
// Disable all authenticators
authnames := store.GetAuthHandlerNames()
authnames := store.GetAuthNames()
for _, name := range authnames {
if err := store.GetAuthHandler(name).DelRecords(uid); err != nil {
log.Println("replyDelUser: failed to delete user auth record", msg.Del.User, name, err, s.sid)