--- /dev/null
+package App::EzPz::UserStore;
+
+use App::EzPz::User;
+use Scalar::Util 'blessed';
+use Authen::Htpasswd;
+use Moo;
+
+has ezmlm_bindir => (is => 'ro', required => 1);
+
+has htpasswd_file => (is => 'ro', required => 1);
+
+has _htpasswd => (is => 'lazy');
+
+sub _build__htpasswd {
+ my ($self) = @_;
+ return Authen::Htpasswd->new($self->htpasswd_file);
+}
+
+sub all {
+ my ($self) = @_;
+ return map $self->_inflate_user($_), $self->_htpasswd->all_users;
+}
+
+sub get {
+ my ($self, $name) = @_;
+ if (my $htp_user = $self->_htpasswd->lookup_user($name)) {
+ return $self->_inflate_user($htp_user);
+ } else {
+ return undef;
+ }
+}
+
+sub add {
+ my ($self, $user) = @_;
+ unless (blessed($user)) {
+ $user = App::EzPz::User->new($user);
+ }
+ my $htp_file = $self->_htpasswd;
+ my $htp_user = $user->_htpasswd_user;
+ $htp_file->add_user($htp_user);
+ $htp_user->file($htp_file);
+ return $user;
+}
+
+sub remove {
+ my ($self, $user) = @_;
+ $self->_htpasswd->remove_user($user->_htpasswd_user);
+ return $user;
+}
+
+sub _inflate_user {
+ my ($self, $htp_user) = @_;
+ return App::EzPz::User->new(
+ htpasswd_user => $htp_user,
+ );
+}
+
+sub check_password {
+ my ($self, $name, $password) = @_;
+ return unless my $user = $self->get($name);
+ return $user->check_password($password);
+}
+
+1;