where the 'attr' value of the validate of SocialLoginSerializer is output in django rest framework - django-rest-framework

I wonder where the attrs of validate in drf's SocialLoginSerializer are expressed.
Actually, I want to change the response values ​​when I do social login,
but I don't know where to change them.
Please help me
class SocialLoginSerializer(serializers.Serializer):
...
def validate(self, attrs):
...
if not login.is_existing:
# We have an account already signed up in a different flow
# with the same email address: raise an exception.
# This needs to be handled in the frontend. We can not just
# link up the accounts due to security constraints
if allauth_settings.UNIQUE_EMAIL:
# Do we have an account already with this email address?
account_exists = get_user_model().objects.filter(
email=login.user.email,
).exists()
if account_exists:
raise serializers.ValidationError(
_('User is already registered with this e-mail address.'),
)
login.lookup()
login.save(request, connect=True)
return attrs

Related

Puppet provider prefetch

I am writing a provider to generate self signed certificate using the certdog krestfield API.
I have implemented the create, destroy, exists? method and I can properly manage my certificate by making different call to the API.
I implemented puppet resource using the self.prefetch and self.instances methods. I can retrieve the properties of my resources to be aware of their current state.
My resource contain two sensitive types 'username' and 'password' who are required to make the API calls. I can't store those values on the filesystem and I want the 'puppet resource' command to ignore those types.
Currently when I run 'puppet apply' for the manifest:
certdog_certificate { 'tstpuppet':
ensure => present,
server => 'apiserver',
username => 'apiserver_username',
password => 'apiserver_password',
}
It returns:
Notice: /Stage[main]/Main/Certdog_certificate[tstpuppet]/username: defined 'username' as 'apiserver_username'
Notice: /Stage[main]/Main/Certdog_certificate[tstpuppet]/password: defined 'password' as 'apiserver_password'
Is there a way to hide sensitive types for puppet resources ? How should I process ?
I had to properly define my resource attributes.
The configurable data not part of the persistant state should be parameters as describe in the puppet documentation.
The attributes username and password are now define with newparam instead of newproperty as below.
module Puppet
Type.newtype(:certdog_certificate) do
#doc = 'Manage certificate using certdog REST API'
ensurable do
desc 'Create or remove a certificate'
newvalue(:present) do
provider.create
end
newvalue(:absent) do
provider.destroy
end
defaultto :present
end
newparam(:cert_name, namevar: true) do
desc 'Name of the certificate request'
end
newparam(:username) do
desc 'Username for Certdog API server'
end
newparam(:password) do
desc 'Password for Certdog API server'
end
newproperty(:server) do
desc 'Certdog API server address'
end
end
#john-bollinger Thanks for your explanation, I was missing an important concept of the custom types.

Can not get signed in email using Office 365 REST API

I followed this post http://dev.office.com/code-samples-detail/2142 and Ruby to get user's email address. Here is the code:
# Parses an ID token and returns the user's email
def get_email_from_id_token(id_token)
# JWT is in three parts, separated by a '.'
token_parts = id_token.split('.')
# Token content is in the second part
encoded_token = token_parts[1]
# It's base64, but may not be padded
# Fix padding so Base64 module can decode
leftovers = token_parts[1].length.modulo(4)
if leftovers == 2
encoded_token += '=='
elsif leftovers == 3
encoded_token += '='
end
# Base64 decode (urlsafe version)
decoded_token = Base64.urlsafe_decode64(encoded_token)
# Load into a JSON object
jwt = JSON.parse(decoded_token)
# Email is in the 'preferred_username' field
email = jwt['preferred_username']
end
This function worked very well, I can get user's email address. But today, this function still works without error but the JSON I got not contain user's email address anymore.
Could someone help me? I want to get user's email address. Thank you !
Azure deployed a breaking change to the v2 app model, and you don't get user info by default anymore.
You can read all about it here: https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-preview-oidc-changes/, but to summarize:
The openid scope used to give you basic profile info for the user.
That wasn't in line with the OpenID standard
Azure changed to require that you request the profile scope to get access to that information
For that sample, find this bit:
# Scopes required by the app
SCOPES = [ 'openid',
'https://outlook.office.com/mail.read' ]
And change it to:
# Scopes required by the app
SCOPES = [ 'openid',
'profile',
'https://outlook.office.com/mail.read' ]
Please add profile and email in your scope :
SCOPES = [ 'openid',
'profile',
'email',
'https://outlook.office.com/mail.read' ]

Generate expiring activator token or a key hash in rails manually

I'm trying to verify a link that will expire in a week. I have an activator_token stored in the database, which will be used to generate the link in this format: http://www.example.com/activator_token. (And not activation tokens generated by Devise or Authlogic.)
Is there a way to make this activator token expire (in a week or so) without comparing with updated_at or some other date. Something like an encoded token, which will return nil when decoded after a week. Can any existing modules in Ruby do this? I don't want to store the generated date in the database or in an external store like Redis and compare it with Time.now. I want it to be very simple, and wanted to know if something like this already exists, before writing the logic again.
What you want to use is: https://github.com/jwt/ruby-jwt .
Here is some boilerplate code so you can try it out yourself.
require 'jwt'
# generate your keys when deploying your app.
# Doing so using a rake task might be a good idea
# How to persist and load the keys is up to you!
rsa_private = OpenSSL::PKey::RSA.generate 2048
rsa_public = rsa_private.public_key
# do this when you are about to send the email
exp = Time.now.to_i + 4 * 3600
payload = {exp: exp, discount: '9.99', email: 'user#example.com'}
# when generating an invite email, this is the token you want to incorporate in
# your link as a parameter
token = JWT.encode payload, rsa_private, 'RS256'
puts token
puts token.length
# this goes into your controller
begin
#token = params[:token]
decoded_token = JWT.decode token, rsa_public, true, { :algorithm => 'RS256' }
puts decoded_token.first
# continue with your business logic
rescue JWT::ExpiredSignature
# Handle expired token
# inform the user his invite link has expired!
puts "Token expired"
end

Generating Paypal Signature, 'X-PAYPAL-AUTHORIZATION' in Ruby

Is there any library in Ruby that generates the Signature, 'X-PAYPAL-AUTHORIZATION' header that is required to make calls on behalf of the account holder who has authorized us through the paypal Permissions API.
I am done with the permissions flow and get the required access token, tokenSecret. I feel I am generating the signature incorrectly as all my calls with the the generated 'X-PAYPAL-AUTHORIZATION' fail. They give the following errors:
For NVP call I get:
You do not have permissions to make this API call
And for the GetBasicPersonalData call I get:
Authentication failed. API credentials are incorrect.
Has anyone gone through this in Ruby? What is best way to generate signature. Paypal has just provided some SDK in Paypal, Java, but not the algorithm to generate signature.
Thanks,
Nilesh
Take a look at the PayPal Permissions gem.
https://github.com/moshbit/paypal_permissions
Specifically lib/paypal_permissions/x_pp_authorization.rb
require 'cgi'
require 'openssl'
require 'base64'
class Hash
def to_paypal_permissions_query
collect do |key, value|
"#{key}=#{value}"
end.sort * '&'
end
end
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module XPPAuthorization
public
def x_pp_authorization_header url, api_user_id, api_password, access_token, access_token_verifier
timestamp = Time.now.to_i.to_s
signature = x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
{ 'X-PAYPAL-AUTHORIZATION' => "token=#{access_token},signature=#{signature},timestamp=#{timestamp}" }
end
public
def x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
# no query params, but if there were, this is where they'd go
query_params = {}
key = [
paypal_encode(api_password),
paypal_encode(access_token_verifier),
].join("&")
params = query_params.dup.merge({
"oauth_consumer_key" => api_user_id,
"oauth_version" => "1.0",
"oauth_signature_method" => "HMAC-SHA1",
"oauth_token" => access_token,
"oauth_timestamp" => timestamp,
})
sorted_query_string = params.to_paypal_permissions_query
base = [
"POST",
paypal_encode(url),
paypal_encode(sorted_query_string)
].join("&")
base = base.gsub /%([0-9A-F])([0-9A-F])/ do
"%#{$1.downcase}#{$2.downcase}" # hack to match PayPal Java SDK bit for bit
end
digest = OpenSSL::HMAC.digest('sha1', key, base)
Base64.encode64(digest).chomp
end
# The PayPalURLEncoder java class percent encodes everything other than 'a-zA-Z0-9 _'.
# Then it converts ' ' to '+'.
# Ruby's CGI.encode takes care of the ' ' and '*' to satisfy PayPal
# (but beware, URI.encode percent encodes spaces, and does nothing with '*').
# Finally, CGI.encode does not encode '.-', which we need to do here.
def paypal_encode str
s = str.dup
CGI.escape(s).gsub('.', '%2E').gsub('-', '%2D')
end
end
end
end
Sample parameters:
url = 'https://svcs.sandbox.paypal.com/Permissions/GetBasicPersonalData'
api_user_id = 'caller_1234567890_biz_api1.yourdomain.com'
api_password = '1234567890'
access_token = 'YJGjMOmTUqVPlKOd1234567890-jdQV3eWCOLuCQOyDK1234567890'
access_token_verifier = 'PgUjnwsMhuuUuZlPU1234567890'
The X-PAYPAL-AUTHORIZATION header [is] generated with URL "https://svcs.paypal.com/Permissions/GetBasicPersonalData". (see page 23, and chapter 7, at the link)
NVP stating "You do not have permissions to make this API call" means your API credentials are correct, just that your account does not have permission for the particular API you are trying to call. Something between the two calls you are submitting is not using the same API credentials.
For NVP call I get:
What NVP call?
TransactionSearch (see comments below)
Also, if you haven't already done so, you will want to use the sandbox APP-ID for testing in the sandbox, and you will need to apply for an app-id with Developer Technical Services (DTS) at PayPal to get an App-ID for live.
EDIT:
To use the TransactionSearch API, all you should be submitting is below. You do not need to specify any extra headers.
USER=xxxxxxxxxxxxxxxxxx
PWD=xxxxxxxxxxxxxxxxxx
SIGNATURE=xxxxxxxxxxxxxxxxxx
METHOD=TransactionSearch
VERSION=86.0
STARTDATE=2009-10-11T00:00:00Z
TRANSACTIONID=1234567890
//And for submitting API calls on bob's behalf, if his PayPal email was bob#bob.com:
SUBJECT=bob#bob.com

Ruby: Dynamically defining classes based on user input

I'm creating a library in Ruby that allows the user to access an external API. That API can be accessed via either a SOAP or a REST API. I would like to support both.
I've started by defining the necessary objects in different modules. For example:
soap_connecton = Library::Soap::Connection.new(username, password)
response = soap_connection.create Library::Soap::LibraryObject.new(type, data, etc)
puts response.class # Library::Soap::Response
rest_connecton = Library::Rest::Connection.new(username, password)
response = rest_connection.create Library::Rest::LibraryObject.new(type, data, etc)
puts response.class # Library::Rest::Response
What I would like to do is allow the user to specify that they only wish to use one of the APIs, perhaps something like this:
Library::Modes.set_mode(Library::Modes::Rest)
rest_connection = Library::Connection.new(username, password)
response = rest_connection.create Library::LibraryObject.new(type, data, etc)
puts response.class # Library::Response
However, I have not yet discovered a way to dynamically set, for example, Library::Connection based on the input to Library::Modes.set_mode. What would be the best way to implement this functionality?
Murphy's law prevails; find an answer right after posting the question to Stack Overflow.
This code seems to have worked for me:
module Library
class Modes
Rest = 1
Soap = 2
def self.set_mode(mode)
case mode
when Rest
Library.const_set "Connection", Class.new(Library::Rest::Connection)
Library.const_set "LibraryObject", Class.new(Library::Rest::LibraryObject)
when Soap
Library.const_set "Connection", Class.new(Library::Soap::Connection)
Library.const_set "LibraryObject", Class.new(Library::Soap::LibraryObject)
else
throw "#{mode.to_s} is not a valid Library::Mode"
end
end
end
end
A quick test:
Library::Modes.set_mode(Library::Modes::Rest)
puts Library::Connection.class == Library::Rest::Connection.class # true
c = Library::Connection.new(username, password)

Resources