Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 187 lines (151 sloc) 7.265 kb
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
1 ## @file
2 # This file contains the implementation of the authentication method loader class.
3 #
4 # @author Chris Page <chris@starforge.co.uk>
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 ## @class
20 # Dynamic AuthMethod loader class. This provides the facility to load
21 # AuthMethod subclasses on the fly to support the Auth class. It relies
22 # on information stored in the auth_methods and auth_params tables to
23 # load AuthMethod subclasses, initialise them, and pass them back to
24 # the caller to use.
25 package AuthMethods;
26
27 use strict;
ac474f6 @TheWatcher Switched dynamic module loading to use Module::Load
authored
28 use Module::Load;
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
29
30 our $errstr;
31
32 BEGIN {
33 $errstr = '';
34 }
35
36 # ============================================================================
37 # Constructor
38
39 ## @cmethod $ new(%args)
40 # Construct a new AuthMethods object. This will create a new AuthMethods object
41 # initialised with the provided arguments.
42 #
43 # @param args A hash of arguments to initialise the AuthMethods object with.
44 # @return A new AuthMethods object.
45 sub new {
46 my $invocant = shift;
47 my $class = ref($invocant) || $invocant;
48 my $self = {
49 @_,
50 };
51
52 # Ensure that we have objects that we need
bf644e4 @TheWatcher Updating webperl classes to use Logger rather than Logging.
authored
53 return set_error("cgi object not set") unless($self -> {"cgi"});
54 return set_error("dbh object not set") unless($self -> {"dbh"});
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
55 return set_error("settings object not set") unless($self -> {"settings"});
bf644e4 @TheWatcher Updating webperl classes to use Logger rather than Logging.
authored
56 return set_error("app object not set") unless($self -> {"app"});
57 return set_error("logger object not set") unless($self -> {"logger"});
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
58
59 return bless $self, $class;
60 }
61
62
63 # ============================================================================
64 # Interface code
65
66 ## @method $ available_methods($only_active)
67 # Generate a list of available AuthMethod subclasses. This pulls a list of
68 # auth methods from the database, and returns an array containing the internal
69 # ids.
70 #
71 # @param only_active If true, the returned array will only contain methods
72 # flagged as being active. Otherwise it will contain all
73 # known methods.
74 # @return A reference to an array of method ids.
75 sub available_methods {
76 my $self = shift;
77 my $only_active = shift;
78
79 my $methodh = $self -> {"dbh"} -> prepare("SELECT id FROM ".$self -> {"settings"} -> {"database"} -> {"auth_methods"}.
85e8a22 @TheWatcher Renamed 'active' column to 'enabled' for clarity.
authored
80 ($only_active ? " WHERE enabled = 1 " : " ").
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
81 "ORDER BY priority ASC");
82 $methodh -> execute()
bf644e4 @TheWatcher Updating webperl classes to use Logger rather than Logging.
authored
83 or $self -> {"logger"} -> die_log($self -> {"cgi"} -> remote_host(), "Unable to execute auth method list query: ".$self -> {"dbh"} -> errstr);
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
84
85 my @methods;
86 while(my $method = $methodh -> fetchrow_arrayref()) {
87 push(@methods, $method -> [0]);
88 }
89
90 return \@methods;
91 }
92
93
94 ## @method $ load_method($method_id)
95 # Load the auth method with the specified id and initialise it. This will
96 # dynamically load the method with the specified id, provided it is active,
97 # and return a reference to the method object.
98 #
99 # @param method_id The id of the auth method to load.
100 # @return A reference to an AuthMethod subclass implementing the method
101 # on success, undef on failure or if the method is disabled. If this
102 # returns undef, $self -> {"lasterr"} is set to a message indicating
103 # what went wrong. Note that attempting to load a disabled method is
104 # NOT considered an error: this will return undef, but lasterr will
105 # be empty.
106 sub load_method {
107 my $self = shift;
108 my $method_id = shift;
109
110 $self -> {"errstr"} = "";
111
112 # Fetch the module name first
85e8a22 @TheWatcher Renamed 'active' column to 'enabled' for clarity.
authored
113 my $moduleh = $self -> {"dbh"} -> prepare("SELECT perl_module, enabled FROM ".$self -> {"settings"} -> {"database"} -> {"auth_methods"}."
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
114 WHERE id = ?");
ad8b679 @TheWatcher Fixed brainos.
authored
115 $moduleh -> execute($method_id)
bf644e4 @TheWatcher Updating webperl classes to use Logger rather than Logging.
authored
116 or $self -> {"logger"} -> die_log($self -> {"cgi"} -> remote_host(), "Unable to execute auth method lookup query: ".$self -> {"dbh"} -> errstr);
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
117
118 my $module = $moduleh -> fetchrow_hashref();
d63120e @TheWatcher if($method) and if(!$method) mean very different things!
authored
119 return $self -> self_error("Unknown auth method requested in load_method($method_id)") if(!$module);
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
120
121 # Is the module active? If not, do nothing
85e8a22 @TheWatcher Renamed 'active' column to 'enabled' for clarity.
authored
122 return undef if(!$module -> {"enabled"});
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
123
124 # Module is active, fetch its settings
125 my $paramh = $self -> {"dbh"} -> prepare("SELECT name, value FROM ".$self -> {"settings"} -> {"database"} -> {"auth_params"}."
126 WHERE method_id = ?");
ad8b679 @TheWatcher Fixed brainos.
authored
127 $paramh -> execute($method_id)
bf644e4 @TheWatcher Updating webperl classes to use Logger rather than Logging.
authored
128 or $self -> {"logger"} -> die_log($self -> {"cgi"} -> remote_host(), "Unable to execute auth method parameter query: ".$self -> {"dbh"} -> errstr);
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
129
130 # Build up a settings hash using the standard objects, and settings for the
131 # module loaded from the database.
132 my %settings = ( cgi => $self -> {"cgi"},
133 dbh => $self -> {"dbh"},
134 settings => $self -> {"settings"},
54f7d34 @TheWatcher Expunged last references to Logging.pm. Long live Logger!
authored
135 app => $self -> {"app"}, # Methods shouldn't actually need access to app, but add it anyway in case.
3aee4fe @TheWatcher Argh, typos.
authored
136 logger => $self -> {"logger"});
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
137 while(my $param = $paramh -> fetchrow_hashref()) {
138 $settings{$param -> {"name"}} = $param -> {"value"};
139 }
140
ad8b679 @TheWatcher Fixed brainos.
authored
141 # For readability...
142 my $name = $module -> {"perl_module"};
143
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
144 no strict "refs"; # must disable strict references to allow named module loading.
ac474f6 @TheWatcher Switched dynamic module loading to use Module::Load
authored
145 eval { load $name };
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
146 die "Unable to load auth module $name: $@" if($@);
147
148 my $methodobj = $name -> new(%settings);
149 use strict;
150
151 # Return undef and set error if the call to new returned an error message
152 return $self -> self_error("Unable to load auth module: ".$methodobj)
153 if(!ref($methodobj));
154
155 # Otherwise, return the auth method object.
156 return $methodobj;
157 }
158
159
160 # ============================================================================
161 # Error functions
162
86994d9 @TheWatcher Added error function docs to AuthMethods.
authored
163 ## @cmethod private $ set_error($errstr)
164 # Set the class-wide errstr variable to an error message, and return undef. This
165 # function supports error reporting in the constructor and other class methods.
166 #
167 # @param errstr The error message to store in the class errstr variable.
168 # @return Always returns undef.
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
169 sub set_error { $errstr = shift; return undef; }
170
86994d9 @TheWatcher Added error function docs to AuthMethods.
authored
171
172 ## @method private $ self_error($errstr)
173 # Set the object's errstr value to an error message, and return undef. This
174 # function supports error reporting in various methods throughout the class.
175 #
176 # @param errstr The error message to store in the object's errstr.
177 # @return Always returns undef.
a24bed0 @TheWatcher Modifying implementation of self_error so that doxygen will work (!)
authored
178 sub self_error {
179 my $self = shift;
180 $self -> {"errstr"} = shift;
86994d9 @TheWatcher Added error function docs to AuthMethods.
authored
181
a24bed0 @TheWatcher Modifying implementation of self_error so that doxygen will work (!)
authored
182 return undef;
183 }
080ec2b @TheWatcher Initial version of dynamic AuthMethod loader added.
authored
184
185 1;
186
Something went wrong with that request. Please try again.