I want to print labels from my web application and to do that I am using this packages. (https://github.com/smalot/cups-ipp). Im using the example code provided by the package and when I send PDF file to print Im getting the following error:
Http\Client\Common\Exception\ClientErrorException(401)
Unauthorized
When I look at my printers queue I see the status is aborted and the size of the file is 0KB. I am sure the file is found the right way because when I do some debugging I can see that the stream of the PDF is coming in right but in the request that is send I can't found it back. The request is as followed:
Request {#995 ▼
-method: "POST"
-requestTarget: null
-uri: Uri {#996 ▼
-scheme: ""
-userInfo: ""
-host: ""
-port: null
-path: "/"
-query: ""
-fragment: ""
}
-headers: array:1 [▼
"Content-Type" => array:1 [▼
0 => "application/ipp"
]
]
-headerNames: array:1 [▼
"content-type" => "Content-Type"
]
-protocol: "1.1"
-stream: Stream {#998 ▼
-stream: stream resource #14 ▼
wrapper_type: "PHP"
stream_type: "TEMP"
mode: "w+b"
unread_bytes: 0
seekable: true
uri: "php://temp"
options: []
}
-size: 140
-seekable: true
-readable: true
-writable: true
-uri: "php://temp"
-customMetadata: []
}
}
I don't know if its valuable but my application is build on laravel 5.6.
The code for executing the print job:
public function testPrinter() {
$client = new Client();
$builder = new Builder();
$responseParser = new ResponseParser();
$printerManager = new PrinterManager($builder, $client, $responseParser);
$printer = $printerManager->findByUri('ipp://localhost:631/printers/OKI_ES7131_D66B77');
$jobManager = new JobManager($builder, $client, $responseParser);
$job = new Job();
$job->setName('job create file');
$job->setUsername('kasper');
$job->setCopies(1);
$job->setPageRanges('1');
$job->addFile('/var/www/justproduce/public/helloworld.pdf', 'test');
$job->addAttribute('media', 'A4');
$job->addAttribute('fit-to-page', true);
$result = $jobManager->send($printer, $job);
}
Had to initialize a new client with credentials. Works now.
In my case (docker installation on a Synology NAS) it still needed username and password.
$client = new Client('User', 'password');
Related
I am currently working on the project that I am going to integrate the application of my company and salesforce.
In my case, it seemed that using the JWT for authentication is better. So, I wanted to try it.
but I don't know how to generate JWT and send the proper request to salesforce on Ruby though I read docs.
What I wanted to do is that
1, create application on salesforce (done)
2, create X509 certification and set it on the application on salesforce. (done)
3, create JWT by using the secret key of X509 certification. (I think I've done it )
4, send post request with JWT parameter included in assertion params and grant_type(grant_type= urn:ietf:params:oauth:grant-type:jwt-bearer&) (I got an error)
when I send post request the errors says {"error":"invalid_grant","error_description":"invalid assertion"} so it occurs certainly because of the parameter I sent.
the code I randomly wrote is something like this.
require 'jwt'
require 'json'
require 'net/http'
require 'uri'
payload = {
"sub": "abel#example.com", ← my account on salesforce
"iss": "3MVG9pe2TCoA1PasbdvjabsodyoQFZTn0Rjsdbfjbasojdbn;oajs", ← the consumer key of the application on salesforce.
"aud": "https://test.salesforce.com"
}
public_key = Base64.urlsafe_encode64(
'USqTxNC7MMIeF9iegop3WeDvFL
075JSUECgYEA76FNJLeStdq+J6Fj2ZBYdDoeuDHv3iNA0nnIse9d6HnjbdrdvjmV
rT1CJuHh9gnNKg4tyjkbpc9IVj4/GF0mNUCgYEAynvj
qOYCzts4W7Bdumk6z8QULJ5QoYCrAgFtwra9R1HDcxTz+GPgJOVx2QBX+aQbDOaD
WV1s9WqE0/Lfi/VVUEzg1hZ8326buGRk1DRVG2Oa48==') ← this is public_key example of the certification.
rsa_private = OpenSSL::PKey::RSA.generate 2048
rsa_public = rsa_private.public_key
token = JWT.encode payload, rsa_private, 'RS256'
puts token
decoded_token = JWT.decode token, rsa_public, true, { algorithm: 'RS256' }
puts decoded_token
post = {
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion': token
}
uri = URI.parse('https://login.salesforce.com/services/oauth2/token')
https = Net::HTTP.new(uri.host, 443)
https.use_ssl = true
response = https.post(uri.path, post.to_query)
print response.body
the PHP version of what I want to achieve is something like this.
<?php
require_once './vendor/autoload.php';
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
// login URL
// production: https://login.salesforce.com
// Sandbox: https://test.login.salesforce.com
define('LOGIN_URL', 'https://test.salesforce.com');
//consumer key
define('CLIENT_ID', <<consumer key of the application on salesforce>>);
//user ID
define('USER_ID', 'xxxxx#example.com');
function createjwt() {
$signer = new Sha256();
$privateKey = new Key('file://cert/server.key'); ← probably the key from certification
$time = time();
$token = (new Builder())->issuedBy(CLIENT_ID) // iss: consumer key
->permittedFor(LOGIN_URL) // aud: Salesforce login URL
->relatedTo(USER_ID) // sub: Salesforce user ID
->expiresAt($time + 3 * 60) // exp: within three mins
->getToken($signer, $privateKey);
return $token;
}
$jwt = createjwt();
echo $jwt;
function auth() {
$jwt = createjwt();
$post = array(
'grant_type' => GRANT_TYPE,
'assertion' => $jwt,
);
$curl = curl_init();
curl_setopt( $curl, CURLOPT_URL, AUTH_URL );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $post );
$buf = curl_exec( $curl );
if ( curl_errno( $curl ) ) {
exit;
}
curl_close( $curl );
$json = json_decode( $buf );
$accinfo = array(
// URL to access
'instance_url' => $json->instance_url,
// Bearer token in order to access
'access_token' => $json->access_token,
);
return $accinfo;
}
$accinfo = auth();
EDIT
I changed a code a lot. But I still have different error that says 'initialize': Neither PUB key nor PRIV key: nested asn1 error (OpenSSL::PKey::RSAError)' around #private_key definition.
I read this and tried changing the string in private_key.pem to in one line but I didn't work ( maybe I did in a wrong way) and didn't understand the meaning of incorrect password (mentioned as the second answer) What causes "Neither PUB key nor PRIV key:: nested asn1 error" when building a public key in ruby?
def initialize
#cert_file = File.join(File.dirname(__FILE__), *%w[private_key.pem])
# #cert = Base64.urlsafe_encode64(#cert_file)
# print #cert_
# #cert_file = File.join(File.dirname(__FILE__), *%w[server.csr])
#base_url = "https://test.salesforce.com"
#auth_endpoint = "/services/oauth2/authorize"
#token_request_endpoint = "/services/oauth2/token"
#token_revoke_endpoint = "/services/oauth2/revoke"
#username = "my username"
#client_id = "pe2TCoA1~~~~" client_id
#private_key = OpenSSL::PKey::RSA.new(File.read(#cert_file))
# #private_key = OpenSSL::PKey::RSA.generate(private_key)
#rsa_public = #private_key.public_key
# #private_key = OpenSSL::PKey::RSA.new(File.read(#cert_file))
end
def claim_set
{
iss: #client_id,
sub: #username,
aud: #base_url,
exp: (Time.now + 3.minutes).to_i.to_s
}
end
def jwt_bearer_token
JWT.encode(self.claim_set.to_s, #rsa_public, 'RS256')
end
def request_auth
post = {body: {grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: jwt_bearer_token}}
uri = URI.parse("#{#base_url}#{#token_request_endpoint}")
https = Net::HTTP.new(uri.host, 443)
https.use_ssl = true
response = https.post(uri.path, post.to_query)
print response.body
end
Salesforce.new.request_auth
end
Any advices are appreciated.
Thank you
I am developing a Angular based website in which a user is required to login using a custom OAuth2 third party authentication provider. .Net core web API is the backend. The response received from the user end point is in JSON and it is having the following format:
{
"dataSources": {
"profile": {
"username": "xyz"
}
},
"profile": {
"id": "87dfkajdfd998df"
},
"errors": {}
}
The code I am currently using is as follows:
builder.AddOAuth(oauth2Configuration.Issuer,
options => {
options.ClientId = oauth2Configuration.ClientId;
options.ClientSecret = oauth2Configuration.ClientSecret;
options.Scope.Add(oauth2Configuration.Scope);
options.ClaimsIssuer = oauth2Configuration.Issuer;
options.CallbackPath = new PathString(oauth2Configuration.ResponseType);
options.AuthorizationEndpoint = oauth2Configuration.Authority;
options.TokenEndpoint = oauth2Configuration.EndSessionEndpoint;
options.UserInformationEndpoint = oauth2Configuration.UserInfoEndpoint;
options.SaveTokens = true;
// Below mapping does not seem to work
options.ClaimActions.MapJsonSubKey(ClaimTypes.Name, "dataSources", "profile.username");
options.ClaimActions.MapJsonKey(ClaimTypes.SerialNumber, "profile.id");
// Remaining code
})
After authenticating with the above code, the claims list is always empty.
Has anyone encountered a similar situation in which claim mapping was done for custom JSON data?
That seems the OAuth authentication handler itself won't help call the endpoint , you need to manually make a call to obtain use's profile from UserInfo endpoint in OnCreatingTicket event :
OnCreatingTicket = async context =>
{
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var user = JObject.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(user);
}
And make claim mapping manually based on your scenario - parse/read the json using JSON.NET and add to user's princple . Please refer to below articles for code samples :
https://www.jerriepelser.com/blog/authenticate-oauth-aspnet-core-2/
https://stackoverflow.com/a/46064936/5751404
I want to create a basic shiny app wherein I can type a keyword in the text input box and when i click submit the output should be a Data table of the recent tweets having the keyword typed in the text input box. I also need to find a way to automatically enable the handshake between my app and twitter using setup_twitter_oauth. I have created the following app.R file
library(shiny)
library(twitteR)
ui <- fluidPage(
titlePanel("Basic Twitter Search App"),
textInput("twitter", "Search Keyword"),
actionButton("click", label = "Search Tweets"),
dataTableOutput("table")
)
server <- function(input, output){
source(file = 'oauth.RData') #file containing the credentials
output$table <- renderDataTable
(
{
observeEvent(input$twitter, {searchTwitter(input$twitter, n=1500)
})
})
}
shinyApp(ui = ui, server = server)
but when I run the code (Run App), the following error occurs :
Error in orig(name = name, shinysession = self) :
unused arguments (name = name, shinysession = self)
Warning: Unhandled error in observer: client error: (400) Bad Request
observeEvent(input$twitter)
Thank You #Jimbo. After many failed experiments, the following code worked:
library(shiny)
ui <- fluidPage(
textInput("handle", "Search Tweets:"),
sliderInput("maxTweets","Number of recent tweets to use for analysis:",min=5,max=1500, value = 5),
downloadButton("download", "Download File"),
dataTableOutput("table")
)
server <- function(input, output) {
library(twitteR)
consumerKey = "My key"
consumerSecret = "My secret"
accessToken = "My token"
accessSecret = "My secret"
my_oauth <- setup_twitter_oauth(consumer_key = consumerKey, consumer_secret = consumerSecret,
access_token = accessToken, access_secret = accessSecret)
output$table <- renderDataTable({
TweetFrame<-function(searchTerm, maxTweets)
{
twtList<-searchTwitter(searchTerm,n=maxTweets)
twtList1<- do.call("rbind",lapply(twtList,as.data.frame))
twtList1$text<-iconv(twtList1$text, 'UTF-8', 'ASCII') #WILL THIS SOLVE THE UTF ENCODING PROBLEM: http://lists.hexdump.org/pipermail/twitter-users-hexdump.org/2013-May/000335.html
return(twtList1)
}
entity1<-reactive({entity1<-TweetFrame(input$handle, input$maxTweets)})
output$table <- renderDataTable({tab<-entity1()[1]})
output$download <- downloadHandler(filename = function() {paste(input$handle, '.csv', sep='')},
content = function(file){
write.csv(entity1(), file)
}
)
})
}
shinyApp(ui = ui, server = server)
Although I still haven't been able to figure out how to automatically enable the user authentication (without user intervention). Any help in this regards will be greatly appreciated.
server <- function(input, output){
source(file = 'oauth.RData') #file containing the credentials
output$table <- renderDataTable({
test <- searchTwitter(input$twitter, n=1500)
return(test)
})
}
This should work as long as searchTwitter returns a df or a matrix
I created a task to automate emailing a report in Symfony 1.4. Both this task and a related module for viewing in the web share a custom PHP class file. The task is able to pull in the data correctly, but I have not been able to get it to send out the email. I attempted to follow the official Symfony 1.4 documentation as well as a number of examples from a Google search, but none are solving my problem. The terminal isn't displaying any error either.
My Code:
<?php
require_once sfConfig::get('sf_lib_dir').'/vendor/sesame/reports/reports.class.php';
//use reports;
class reportsTask extends sfBaseTask
{
protected function configure()
{
// // add your own arguments here
// $this->addArguments(array(
// new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'),
// ));
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
new sfCommandOption('type', null, sfCommandOption::PARAMETER_OPTIONAL, 'The output type of the report', 'email')
// add your own options here
));
$this->namespace = '';
$this->name = 'reports';
$this->briefDescription = '';
$this->detailedDescription = <<<EOF
The [reports|INFO] task does things.
Call it with:
[php symfony reports|INFO]
EOF;
}
protected function execute($arguments = array(), $options = array())
{
$databaseManager = new sfDatabaseManager($this->configuration);
$databaseManager->loadConfiguration();
$reports = new reports();
$output = $reports->buildReport($options['type']);
switch($options['type']){
case 'csv':
echo $output;
break;
case 'email':
$message = $this->getMailer()->compose($output['from'], $output['to'], $output['subject']);
$message->setBody($output['body']['content'], $output['body']['type']);
$message->attach(Swift_Attachment::newInstance($output['attachment']['content'], $output['attachment']['name'], $output['attachment']['type']));
$this->getMailer()->sendNextImmediately()->send($message) or die('email failed to deliver');
$output = array('status'=>'success', 'to'=>$output['to']);
default:
$this->logSection('results', json_encode($output));
}
}
}
The terminal command being attempted from the project root:
php symfony reports
Any answers leading to the right path would be most helpful. Please keep in mind that I need to stay with version 1.4. The server is capable of sending off emails and my module version does just that when invoked by a URL. I need it to run on the command line though so I can set up a cron.
I am attempting to gain three-legged Oauth access, but I can't get the first step to work. My code so far:
include("OAuth.php");
$consumer_key = "anonymous";
$consumer_secret = "anonymous";
define("URI", "http://www.google.com");
$request_token_url = URI.'/accounts/OAuthGetRequestToken?scope=https%3A%2F%2Fwww.google.com%2Fh9%2Ffeeds%2F';
$parsed = parse_url($request_token_url);
$params = array();
$oauth_consumer = new OAuthConsumer($consumer_key, $consumer_secret, NULL);
$req_req = OAuthRequest::from_consumer_and_token($oauth_consumer, NULL, "GET", $request_token_url, $params);
$sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$req_req->sign_request($sig_method, $oauth_consumer, NULL);
$request = $req_req->to_url();
$session = curl_init($request);
curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);
// Make the request
$response = curl_exec($session);
//Error Handling:
// there is an error while executing the request,
if (!$response) {
$response = curl_error($curl);
}
curl_close($session);
parse_str($response, $params);
$oauth_token = $params['oauth_token'];
$oauth_token_secret = $params['oauth_token_secret'];
$_SESSION['CONSUMER_KEY'] = $consumer_key;
$_SESSION['CONSUMER_SECRET'] = $consumer_secret;
$_SESSION['REQUEST_TOKEN'] = $oauth_token;
$_SESSION['REQUEST_TOKEN_SECRET'] = $oauth_token_secret;
print_r($_SESSION);
I'm using OAuth.php.
The returning array does not give me anything:
Array (
[CONSUMER_KEY] => googlecodesamples.com
[CONSUMER_SECRET] => [REQUEST_TOKEN] => [REQUEST_TOKEN_SECRET] =>
)
I found this on the Google Oauth Reference
If your application is not registered, select HMAC-SHA1 and use the following key and secret:
consumer key: "anonymous" consumer
secret: "anonymous"
I have altered the consumer_key and consumer_secret variables but the returning array remains empty.
I'm not sure what I'm doing wrong this is a basic H9 sandbox development procedure; any advice would help.
Well I have figured this one out,
When I printed the response of the curl I got a message which said:
This URL has moved here:
https://www.google.com/accounts/OAuthGetRequestToken?oauth_consumer_key=anonymous%20%20%20%20[amp;oauth_nonce]%20=%3E%20828f80d4cec64b5b6fcca5010e2aa952%20%20%20%20[amp;oauth_signature]%20=%3E%20H+WrK1WIhyFEkrHRBvjpzcVLFvs=%20%20%20%20[amp;oauth_signature_method]%20=%3E%20HMAC-SHA1%20%20%20%20[amp;oauth_timestamp]%20=%3E%201282773417%20%20%20%20[amp;oauth_version]%20=%3E%201.0%20%20%20%20[amp;scope]%20=%3E%20https://www.google.com/h9/feeds/
So once I changed the $request_token_url to this, it worked like a charm and I finally have one-leg!! two left :)