return $self->patron_not_found;
} elsif ($permit_test eq 'expired') {
return $self->patron_is_expired;
+ } elsif ($permit_test eq 'not_permitted') {
+ return $self->patron_not_permitted;
+ } elsif ($permit_test eq 'has_penalties') {
+ return $self->patron_has_penalties;
} else {
return $self->patron_is_blocked;
}
return $self->patron_is_expired;
} elsif ($permit_test eq 'blocked') {
return $self->patron_is_blocked;
+ } elsif ($permit_test eq 'not_permitted') {
+ return $self->patron_not_permitted;
+ } elsif ($permit_test eq 'has_penalties') {
+ return $self->patron_has_penalties;
} else {
return $self->backend_error;
}
return Apache2::Const::DECLINED;
}
+# patron does not have required permission to authenticate;
+# treat them as being not found
+sub patron_not_permitted {
+ my $self = shift;
+ return $self->patron_not_found;
+}
+
+# patron has blocking penalties;
+# treat them as being blocked
+sub patron_has_penalties {
+ my $self = shift;
+ return $self->patron_is_blocked;
+}
+
1;
return $self->error('patron_not_found');
}
-# patron is barred or has blocking penalties
+# patron is barred/blocked
sub patron_is_blocked {
my $self = shift;
return $self->error('patron_is_blocked');
}
+# patron does not have permission to authenticate
+sub patron_not_permitted {
+ my $self = shift;
+ return $self->error('patron_not_permitted');
+}
+
+# patron has blocking penalties
+sub patron_has_penalties {
+ my $self = shift;
+ return $self->error('patron_has_penalties');
+}
+
# patron is expired
sub patron_is_expired {
my $self = shift;
SELECT INTO perm code FROM permission.perm_list WHERE id = profile.perm;
IF permission.usr_has_perm(usr.id, perm, profile.context_org) IS FALSE THEN
- RETURN 'not_found';
+ RETURN 'not_permitted';
END IF;
IF usr.expire_date < NOW() AND profile.allow_expired IS FALSE THEN
IF penalty_count > 0 THEN
-- User has penalties that match this block, so auth is not permitted.
-- Don't bother testing the rest of the block list.
- RETURN 'blocked';
+ RETURN 'has_penalties';
END IF;
END LOOP;
END IF;
--- /dev/null
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION actor.permit_remoteauth (profile_name TEXT, userid BIGINT) RETURNS TEXT AS $func$
+DECLARE
+ usr actor.usr%ROWTYPE;
+ profile config.remoteauth_profile%ROWTYPE;
+ perm TEXT;
+ context_org_list INT[];
+ home_prox INT;
+ block TEXT;
+ penalty_count INT;
+BEGIN
+
+ SELECT INTO usr * FROM actor.usr WHERE id = userid AND NOT deleted;
+ IF usr IS NULL THEN
+ RETURN 'not_found';
+ END IF;
+
+ IF usr.barred IS TRUE THEN
+ RETURN 'blocked';
+ END IF;
+
+ SELECT INTO profile * FROM config.remoteauth_profile WHERE name = profile_name;
+ SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( profile.context_org );
+
+ -- user's home library must be within the context org
+ IF profile.restrict_to_org IS TRUE AND usr.home_ou NOT IN (SELECT * FROM UNNEST(context_org_list)) THEN
+ RETURN 'not_found';
+ END IF;
+
+ SELECT INTO perm code FROM permission.perm_list WHERE id = profile.perm;
+ IF permission.usr_has_perm(usr.id, perm, profile.context_org) IS FALSE THEN
+ RETURN 'not_permitted';
+ END IF;
+
+ IF usr.expire_date < NOW() AND profile.allow_expired IS FALSE THEN
+ RETURN 'expired';
+ END IF;
+
+ IF usr.active IS FALSE AND profile.allow_inactive IS FALSE THEN
+ RETURN 'blocked';
+ END IF;
+
+ -- Proximity of user's home_ou to context_org to see if penalties should be ignored.
+ SELECT INTO home_prox prox FROM actor.org_unit_proximity WHERE from_org = usr.home_ou AND to_org = profile.context_org;
+
+ -- Loop through the block list to see if the user has any matching penalties.
+ IF profile.block_list IS NOT NULL THEN
+ FOR block IN SELECT UNNEST(STRING_TO_ARRAY(profile.block_list, '|')) LOOP
+ SELECT INTO penalty_count COUNT(DISTINCT csp.*)
+ FROM actor.usr_standing_penalty usp
+ JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
+ WHERE usp.usr = usr.id
+ AND usp.org_unit IN ( SELECT * FROM UNNEST(context_org_list) )
+ AND ( usp.stop_date IS NULL or usp.stop_date > NOW() )
+ AND ( csp.ignore_proximity IS NULL OR csp.ignore_proximity < home_prox )
+ AND csp.block_list ~ block;
+ IF penalty_count > 0 THEN
+ -- User has penalties that match this block, so auth is not permitted.
+ -- Don't bother testing the rest of the block list.
+ RETURN 'has_penalties';
+ END IF;
+ END LOOP;
+ END IF;
+
+ -- User has passed all tests.
+ RETURN 'success';
+
+END;
+$func$ LANGUAGE plpgsql;
+
+COMMIT;
+
Patron not found.
[% ELSIF ctx.error_msg == 'patron_is_blocked' %]
Your account is blocked.
+ [% ELSIF ctx.error_msg == 'patron_has_penalties' %]
+ Your account has penalties which prevent authentication.
+ [% ELSIF ctx.error_msg == 'patron_not_permitted' %]
+ Your account is not permitted to authenticate.
[% ELSIF ctx.error_msg == 'patron_is_expired' %]
Your account is expired.
[% ELSE %]