NAME

Authenticator - placeholder class for Authenticator modules in the Aurora REST-server.

SYNOPSIS

my $db=AuroraDB::new(...);
my $cfg=Settings::new(...);

my $auth=Authenticator::new(db=>$db,cfg=>$cfg);

my $authstr="this_is_a_authentication_string";

my $userid=$auth->validate($authstr);

if (!$userid) { print "Failed to authenticate: ".$auth->error()."\n"; }

my $longevity=$auth->longevity();

$auth->save($authstr);

my $newauthstr=$auth->generate($authstr);

DESCRIPTION

This module is a placeholder class for authentication modules in the Aurora REST-server and is built around the notion of an authentication string whose format is defined by the inheriting class. The return value from the validate()-method is to be the userid from the Aurora DB or 0 if it failed. Undef upon some failure.

CONSTRUCTOR

new()

Class constructor.

Authenticator::new();

Required input is the parameters "db" and "cfg". These are to be the AuroraDB instance (db) and the Settings instance (cfg) that defines the configuration settings of Aurora.

Return instance upon success.

METHODS

define()

Defines the classes structures with information that are specific to the class in question. It is to be overridden by the inheriting class and are called by the new-constructur method. It is not to be called by the user of the class.

It takes no input.

The method needs to define four structures called type ($self->{type}), locations ($self->{MD}), namespaces ($self->{namespaces}) and constraints ($self->{constraints}).

The type is just the textual type of the Authenticator and is returned when calling the type()-method. Usually should be set to the Authenticator-class name, eg. "AuroraID".

The first thing to define is the location-structure which contains all the shortnames for the namespaces of the Authenticator-class:

$MD => (
        "authstr" => "system.authenticator.placeholder.authstr",
        "expire"  => "system.authenticator.placeholder.expire",
      );
# save it
$self->{MD}=\%MD;

All code that later need to get the shortnames can refer to $self->{MD} to get them shortnames HASH. This is to easily allow remapping of the namespace without affecting the code. It also eliminates the need to remember and write correctly long namespace locations.

The namespaces structure is of type HASH and contains all the metadata namespaces and their settings that the authenticator-module in question uses. It also allows for the inheriting child-class to input his own settings to the namespace. Two option-values for each namespace-value is reserved/protected: "public" and "storable". These cannot be used for any other purpose and has the following purpose: "public" defines if the namespace value is public to everyone outside the authenticator-module or not? The "storable" settings defines if the value in question can be stored to the database or not.

The structure looks like this:

NS => (
        $MD{"authstr"} => {
                            public => 0,
                            storable => 1,
                          },
        $MD{"expire"} => {
                           public => 1,
                           storable => 1,
                         },

      )

All keys entered into the structure are to refer to the $MD-structure. It is also important that the authstr-key is defined for all classes that are to be storable, that is where the authkey is to be stored in the database, because the storable()-method refers to the namespace-structures $MD{"authstr"}{storable} to find out if it is allowed to be stored or not? If no key for this is found, or the storable-setting is 0, the storable()-method will return 0 for storable which will impact what eg. the save()-method can do.

The constraints structure is also of type LIST and is to contain these values in the following order:

- Textual format of the authstr (eg. EMAIL,PASSWORD).
- Maxmimum length of the authstr in number of characters.
- Regex with valid format for the authstr.
- Default longevity setting that will override faulty or missing settings in the config-file.

The regex for the authstr for storable Authenticator-classes is to include enveloping paranthesis for the user ID and the authentication CODE. User ID is expressed as a email-address (which is unique in the AURORA DB). The enveloping paranthesis is to make it possible to address the ID and CODE as $1 and $2 respectively.

It always return 1.

validate()

Validates the string against the data input to the class.

Input required is the authstr that one wants to validate against the Aurora database. The method is to be overridden by the inheriting class and perform validation based upon that class type. There are several ways of identifying a USER entity for a user in the database, but always by comparing some metadata value of the USER-entity against the authstr given to the method.

Returns AURORA userid upon successful validation of credentials or 0 upon failure.

Failure reason can be fetched by calling the error()-method.

deValidate()

Removes any validation credentials achieved by the class in question.

Input expected: authstr. Its the authstr that one uses to validate against the AURORA database. This method is to be overridden by the inheriting class and remove any validation credentials that class has achieved. If no validation credentials are achieved of any permanent nature, always return 0 (false).

Returns 1 upon successful removal on any credentials, 0 upon not having any credentials to remove or undef if some failure.

Check the error()-method for more information upon failure.

generate()

Generates an authstr based upon a raw string input. The method can be used to generate a valid authstr based upon some raw input from the user or the system. What the generate method does is up to the inheriting class and it is to be overridden.

Still it is expected that the input is the authstr according to the format defined in the constraints-structure. It will so rework the authstr to include the CODE part in the form that can be stored in the AURORA database.

It cases where the Authenticator-class does not generate a storable authenticator CODE-part (of the authstr) this method shall return a checked and cleaned version of the authstr.

Input to the method is the raw string to generate an authstr based upon according to the return of the constraints()-method.

Return value is always a string or undef upon some failure. The exact error is to be read from the error-method.

namespacesData()

Get the data for the namespaces keys.

Takes only one input: authstr. It uses the authstr to deteremine if it is a valid user or not and then to fetch that users data for the defined namespaces keys.

Upon success it returns the data in the database for the namespaces where such data exists as a HASH-reference. Upon failure returns undef. Please check the error()-method for more information on the failure in question.

The HASH-structure is as follows:

data => (
          KEYNAMEa  => SCALAR # value of given key from namespaces-definition
          .
          .
          KEYNAMEz  => SCALAR # value of given key from namespaces-definition

        )

Please note that it only return data where it exists, and if no data is found in the database for the given key, nothing will be returned (not even the key). Further also note that this method returns all values of given keys regardless of the "public"-setting of the namespaces HASH (see the define()-method). It is up to the caller to "wash" the returned data to ensure that not too much is given away to a third party without looking at its public-setting.

save()

Saves the authstr to database.

Accepts two inputs in the following order: authstr and expire. Authstr sets the authstr to save according to the format in constraints. Expire sets the actual time when the authstr expires and are not usable anymore. Expire time is set in unixtime and it is optional. It will default to current time + return from the longevity()-method.

An expire-setting of 0 should mean never expire (but it is is up to the inheriting class how this is implemented in the validate()-method). So a specific class may not allow "eternal" validation strings. If no expire-parameters is set, it will generate one from constraints and settings in the configuration file. See the longevity()-method for more information.

The method uses the generate()-method to rework the authstr to a version that is ready to be stored. It uses the constraints()-settings to get the user ID- and CODE-part of of the string. The method is dependant upon that the Authenticator-class in question is storable. See the storable()-method for more information.

Returns 1 if successful, 0 if something failed. Please check the error()-method upon failure.

type()

Return the Authenticator class type as defined in the define()-method. No input is required and returns the textual type of the class.

longevity()

Returns the longevity setting of an authentication string.

It returns how long in seconds an authentication string is valid for. This setting is retrieved in the following steps:

  - The configuration file is read from the cfg-instance to the new()-method. If it finds a setting called 
system.auth.CLASSNAME.longevity, it is of integer type, it uses this as the longevity setting. CLASSNAME here is what 
the type()-method reports, but in lowercase.
  - If it cant find the longevity setting in the configuration file, it uses the default from the constraints()-
method.

It returns the longevity setting in seconds.

namespaces()

Returns the namespaces in the Aurora db for the authstr and the expire date as a HASH-reference.

Accepts to input.

See the define()-method for more information on the structure of the namespaces HASH.

locations()

Returns the locations in the Aurora db for the authstr and the expire date as a HASH-reference.

Accepts no input.

See the define()-method for more information on the structure of the location HASH.

constraints()

Returns the constraints of the raw string to be generated to an authstr by the generate()-method. It is defined by the define()-method.

It requires no input and the return value is a LIST in the order defined in the define()-method. See the define()-method for more information.

storable()

Returns if the Store-class result from the generate()-method is meant to be stored in the Aurora DB.

No input accepted.

Returns 0 for not meant to be stored and 1 for meant to be stored.

email()

Returns email (ID) of user in the authstr.

Takes the whole authstr as input.

Returns the email address in the authstr identifying the user or a blank string if it does not contain the user email (ID).

Upon some failure returns undef. Check the error()-method for more information upon failure.

id()

Attempts to find and return the user entity id of the user in the authstr.

Takes authstr as input.

Returns the user entity id upon success or 0 upon some failure. Please check the error()-method for more information upon failure.

This method is to be overridden by the inheriting class.

anonymize()

Anonymize user data in the database.

Input parameter is "id". It defines the database user id for the user to anonymize data for.

Returns 1 upon success, 0 upon some failure. Check the error()-method for more information upon failure.

This method is a placeholder and is required to be overridden by the inheriting class who knows best which of its authentication data that needs to be anonymized. Only information that may uniquely identify a person/individual is required to be removed, so hashed passwords can still remain (and might open a path to restore the account in case of such requests by the fact that the user remembers the password). Such things as email, name, username and so on needs to be anonymized.

error()

Returns last error from Authenticator-class.

errorcode()

Returns the error code of the last error (see the error()-method).

This error code is to be used by all inheriting sub-classes of Authenticator to set codes for the REST-server that uses the Authenticator-plugins. Error codes are set directly in the instance by using $self->{errorcode}=NN. See the ErrorAlias-module for more information on setting valid codes.