Openid - User details after authentication - perl

I am trying to use Catalyst::Authentication::Credential::OpenID to authenticate users from Google.
Once authentication is successful, I get a Catalyst::Plugin::Authentication::User::Hash object as my user.
If users are logging in for the first time in my application, I want to get details of user from OpenID provider and store them in my DB.
This is to ease the process of registration, I want as much details from OpenID as possible.
But at least first name, last name, email etc..
But I am not able to achieve it. As an example, if I call, I get exception saying method *url,display * are not defined.
$c->user->url
$c->user->display
Any help in sorting it out is helpful.

After reading the Catalyst manual a number of times and getting some clue from Catalyst mailing lists, I came to know that we have to use extensions.
Because we will be using a number of different realms, I used progressive class.
Here is sample configuration used in my app, currently supporting only openID.
This uses Simple Registration Schema for OpenID Attribute Exchange defined at
http://www.axschema.org/types/
'Plugin::Authentication' => {
default_realm => 'progressive',
realms => {
progressive => {
class => 'Progressive',
realms => [ 'openid' ],
},
openid => {
credential => {
class => "OpenID",
store => {
class => "OpenID",
},
consumer_secret => "Don't bother setting",
ua_class => "LWP::UserAgent",
# whitelist is only relevant for LWPx::ParanoidAgent
ua_args => {
whitelisted_hosts => [qw/ 127.0.0.1 localhost /],
},
extensions => [
'http://openid.net/srv/ax/1.0' => {
mode => 'fetch_request',
'type.nickname' => 'http://axschema.org/namePerson/friendly',
'type.email' => 'http://axschema.org/contact/email',
'type.fullname' => 'http://axschema.org/namePerson',
'type.firstname' => 'http://axschema.org/namePerson/first',
'type.lastname' => 'http://axschema.org/namePerson/last',
'type.dob' => 'http://axschema.org/birthDate',
'type.gender' => 'http://axschema.org/person/gender',
'type.country' => 'http://axschema.org/contact/country/home',
'type.language' => 'http://axschema.org/pref/language',
'type.timezone' => 'http://axschema.org/pref/timezone',
required => 'nickname,fullname,email,firstname,lastname,dob,gender,country',
if_available => 'dob,gender,language,timezone',
}
],
},
}
}
},

Related

How to check if authenticated user is handler of REST resourece

I've developing a REST service on Yii2 and Angular 2 client. Using Bearer JWT authentication.
For example there is a uri: http://127.0.0.1/v1/accounts/123456/meters, which should return all user's meters by account, which he own.
Applied router rule:
'<accountId:\w+>/<action:[\w-]+>' => '<action>',
Controllers has following behaviors:
'authenticator' => [
'class' => HttpBearerAuth::className(),
'except' => ['options']
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['meters'],
'roles' => ['#'],
]
]
]
Action AccountController::actionMeters looks:
public function actionMeters($accountId)
{
// Call MS SQL procedure
$meters = Yii::$app->db->createCommand("EXEC [getMetersByAccountId] :accountId")->bindValue(':accountId', $accountId)->queryAll()
return $meters;
}
But in this way authenticated user can get (if modify GET accountId parameter) meters, which belongs to another user.
I have a user_account table in database, which link users and accounts, but I don't know in which place of application should I perform a checking properly.
How to make a check if authenticated user has an access to this resource by specified accountId parameter?
Thank you.
I've found solution to determine matchCallback in access rule. Now it's look:
[
'allow' => true,
'actions' => ['meters'],
'roles' => ['#'],
'matchCallback' => function() {
return Yii::$app->user->identity->user->hasAccount(Yii::$app->request->get('accountId'));
}
],
And define hasAccount method in User model:
public function hasAccount($accountId) {
return $this->hasOne(UserAccount::className(), ['user_id' => 'id'])->where(['account_id' => $accountId])->exists();
}
It's work correct. Is it a proper solution?

PE Puppet Console and manage multiple node user accounts

I'm new to puppet and using Puppet Enterprise with the module from puppet for accounts. https://forge.puppet.com/puppetlabs/accounts
I'd like to be able to manage the user account details from the PE console for multiple users.
The best I can seem to get to is managing them within
/etc/puppetlabs/code/environments/production/manifests/site.pp
Which contains:
node default {
accounts::user { 'jeff':
comment => 'Jeff McCune',
groups => [
'wheel',
],
locked => true,
sshkeys => [
'ssh-rsa AAAA...',
'ssh-dss AAAA...',
],
password => '!!',
ensure => 'present',
}
accounts::user { 'dave':
comment => 'Dave Smith',
groups => [
'wheel',
],
locked => true,
sshkeys => [
'ssh-rsa AAAA...',
'ssh-dss AAAA...',
],
password => '!!',
ensure => 'present',
}
}
I'd ideally I'd like to be able to manage them per PE classification within the console. So each users details can be parameters I enter in the PE console - the number of users would vary, but just need the principle to able to add more than one.
I've tried adding into a manifest but struggled with declaring more than one account. I did that by:
/etc/puppetlabs/code/environments/production/modules/my_app/manifests/init.pp
which contained:
class my_app (
$username => '',
$usercomment => '',
$sshkey ='',
){
accounts::user { $username:
comment => $usercomment,
groups => [
'sudonopw',
],
locked => false,
sshkeys => [
$sshkey,
],
password => '!!',
ensure => present,
}
}
This allowed me to apply this class to any variation of my node classification and allow me to manage those parameters in the PE console. However I couldn't add more than one account to each node, as the class had been declared.
Can anyone give me some pointers.
Thanks

How can i include JWT in Silex with SecurityProvider

I create app with Silex. I'm using for user authentication the "SecurityServiceProvider". The users are stored in the database. My firewall configuration look like:
$app->register(new Silex\Provider\SecurityServiceProvider(), array(
'security.firewalls' => array(
'secure_area_edison' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/', 'check_path' => '/admin/login_check'),
'logout' => array('logout_path' => '/admin/logout', 'invalidate_session' => true),
'users' => function () use ($app) {
return new App\Services\UserProvider($app['db']);
},
),
)
));
Now i want to create a API for my app. The api will return JSON Responses. All functions from the API can be accessed through the uri "/api/".
I found some topics in case of JWT and try to include JWT in my App. But i'm not sure how can include JWT in my app or it's possible to combine the classic authentication with JWT in Silex?
Have someone a example or hint for me?

Facebook Marketing API connections: exclude people

So on the Ads Manager under connections, it gives you the choice to exclude people who used your app as a way to avoid showing ads to your current users.
The marketing API in the doc says you can set a targeting spec: 'app_install_state' which can be set to 'INSTALLED' or 'NOT_INSTALLED' and to quote facebook
must be used in conjunction with promoted_object at adset level
I have tried adding it to the $targeting object as well as adding it on the adset level. But when I go to view the ad set in the ad manager on Facebook the connections part is still unchanged.
'name' => 'Test Ad Set',
'billing_event' => 'APP_INSTALLS',
'optimization_goal' => 'APP_INSTALLS',
'campaign_status' => "PAUSED",
'daily_budget' => 5000,
'bid_amount' => 10,
'campaign_group_id' => $id,
'targeting' => json_encode($targeting),
$targeting = array(
'geo_locations' => array(
'countries' => array('US'),
),
'page_types' => array('mobilefeed'),
'user_os' => array('Android'),
'app_install_state' => 'NOT_INSTALLED',
);
Also tried moving the app_install_state outside of the targeting array to the adset level.
Incase you don't know what am talking about this is the part on the ad manager:

CGI Application Authentication using multiple drivers

I have been trying to authenticate my CGI application through 2 drivers, one that uses username/password stored in the database and other using ldap active directory.
following is the code
$self->authen->config(
DRIVER => [ 'DBI',
DBH => $self->dbh,
TABLE => 'user',
CONSTRAINTS => {
'user.username' => '__CREDENTIAL_1__',
'MD5:user.password' => '__CREDENTIAL_2__'
},
],
DRIVER => [ 'Authen::Simple::LDAP',
host => 'ldapad.company.com',
basedn => 'OU=XXX,OU=XX,DC=XXX,DC=XXX',
binddn => 'CN=usename,OU=Users,OU=XXX,OU=AD,DC=XXX,DC=xxx',
bindpw => 'secret',
filter => '(cn=%s)',
],
CREDENTIALS => [ 'authen_username', 'authen_password' ],
STORE => 'Session',
LOGOUT_RUNMODE => 'logout',
LOGIN_RUNMODE => 'login',
POST_LOGIN_RUNMODE => 'okay',
RENDER_LOGIN => \&my_login_form,
);
How do I make the application check the other driver is not authenticated with one.
Right now, as expected, its the driver listed at the bottom that works and they both do, depending on which was assigned last.
I'm assuming you're using CGI::Application::Plugin::Authentication.
I think there's a small problem in your code, that justifies the fact that only the last of the two works.
Your code is like:
$self->authen->config(
DRIVER => [ 'DBI', ... ],
DRIVER => [ 'Authen::Simple::LDAP', ... ],
CREDENTIALS => [ 'authen_username', 'authen_password' ],
STORE => 'Session',
# ...
);
but $self->authen->config() takes a hash. For example, take a look at this example from the C::A::P::Authentication distribution.
Being a hash, that means that the last DRIVER entry will overwrite the previous ones.
I believe the fix is very simple:
$self->authen->config(
DRIVER => [
[ 'DBI', ... ],
[ 'Authen::Simple::LDAP', ... ],
],
CREDENTIALS => [ 'authen_username', 'authen_password' ],
STORE => 'Session',
# ...
);
You can find an example of this in the module documentation:
http://search.cpan.org/~silasmonk/CGI-Application-Plugin-Authentication/lib/CGI/Application/Plugin/Authentication.pm#config
How do I make the application check the other driver is not authenticated with one.
It sounds to me like you want to check if more than one authentication method works, rather than the last one that works. Could you set up 3 different $self->authen->config() and try to login 3 different times? You use a hash to track the methods that work.