How do I programmatically download a file behind Oracle's OTN login page? - oracle

I'm trying to create a Chocolatey package for the Oracle WebLogic Server binaries. I know that I must pass a special cookie for the "license acceptance". But, I'm getting stuck trying to get past the login form. I've been researching how to get it done with wget or curl and I'm trying to map that to System.Net.WebClient, where applicable.
I have the following so far, which works for other Oracle downloads with license acceptance (like the JDK).
$url = "http://download.oracle.com/otn/nt/middleware/12c/wls/1212/wls1212_dev.zip"
$temp = Join-Path $ENV:TEMP "oracle-weblogic-server.zip"
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$client.Headers.Add("Cookie", "gpw_e24=http://www.oracle.com")
$client = New-Object System.Net.WebClient
$client.DownloadFile($url, $temp)
I've read in a few places that the Oracle download page supports "basic" authentication. Which should mean setting a NetworkCredential. So, I set this before downloading...
$client.Credentials = New-Object System.Net.NetworkCredential("username", "password")
But, the response seems to contain a login page! (here is a fragment of the form). UPDATE: I think only the Oracle support portal supports basic authentication :(
<form action="https://login.oracle.com/mysso/signon.jsp" method="post" name="myForm">
<input type="hidden" name="v" value="v1.4">
<input type="hidden" name="p_submit_url" value="https://login.oracle.com:443/sso/auth">
<input type="hidden" name="p_cancel_url" value="https://edelivery.oracle.com">
<input type="hidden" name="p_error_code" value="">
<input type="hidden" name="ssousername" value="">
<input type="hidden" name="subscribername" value="">
<input type="hidden" name="authn_try_count" value="0">
<input type="hidden" name="contextType" value="external">
<input type="hidden" name="username" value="string">
<input type="hidden" name="contextValue" value="/oam">
<input type="hidden" name="password" value="sercure_string">
<input type="hidden" name="challenge_url" value="https://login.oracle.com/mysso/signon.jsp">
<input type="hidden" name="request_id" value="903089276773533395">
</form>
I also tried writing the authorization header directly, but I got the same result.
$client.Headers.Add("Authorization", "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("${username}:${password}")))
I stumbled on an old message about OTN not allowing command-line authentication. I don't know how to verify that, but other sites are saying the same thing (they might be parroting one source, though). But, I swear I've seen people POSTing credentials with wget and --post-data, I can't find it now.
I played with the WebClient.UploadValues to no avail. Maybe I'm picking the wrong names or the wrong URL? I have noticed some redirects in the responses and when I'm manually watching the traffic (Inspect Element | Network in Chrome). But, I don't know what do with this information!
$login = "https://login.oracle.com/mysso/signon.jsp"
$data = New-Object System.Collections.Specialized.NameValueCollection
$data.Add("username", "username")
$data.Add("password", "password")
$client.UploadValues($login, "POST", $data)
So, first, and most importantly, is there any way to login to OTN from the command line. Second, how do I do it with WebClient?

This method could possibly get you into trouble as it seems like the required login is there to specifically ensure it's a human on the other end.

Related

How to keep the fields of a form after being redirected by login or registration in Laravel?

The business logic is as follows:
Fill out the form to publish a card.
Click on publish card button.
Publish if only if the user is authenticated.
If you are not authenticated, request to log in with the option to register.
If the user is registered or logged in, redirect to the form keeping the fields filled.
This is the logic of what I want to do
Note:
I currently show the login view if it is not authenticated with the help of laravel's Authentication Middleware.
The login view has the option to register.
I do not have much experience in laravel, I would like you could be explicit in your answer.
Try this one
<input type="text" class="form-control" placeholder="Name" name="name" required value="{{ old('name') }}">
this keep old value when you return page.
if you want redirect page with data, use Compact.
for example
$data["name"] = "name"
$data["gender"] = "something"
return view('your blade file path', compact('data'));
and on blade file
<input type="text" class="form-control" placeholder="Name" name="name" required value="{{ $data['name'] }}">

Laravel Fortify :: Calling `updatePassword()` function through Livewire

I'm using Livewire to build my Laravel project, and I'm also implementing the security/authentication layer with Fortify.
For various reasons though, I'm not using Jetstream. With that said, there are clearly some very useful features and techniques which Jetstream employs to do its stuff, and so in the true spirit of creativity, I've "borrowed" the following "update-password" form as an example of how Jetstream uses Livewire to interface with Fortify.
This HTML template is a simplified version of the actual HTML code that goes into building my form, but I've taken out all the styling and labelling complexities etc. so that we can focus only on what's important:
<!-- update-password-form.blade.php (Livewire Template) -->
<form wire:submit.prevent="updatePassword">
<input id="current_password" type="password" name="current_password" required="true" />
<input id="password" type="password" name="password" required="true" />
<input id="password_confirmation" type="password" name="password_confirmation" required="true" />
<button type="submit">Change Password</button>
</form>
As we see, Livewire prevents the default submission of the form, and redirects it to the function updatePassword() in the Livewire class. The function as you can see here looks like this:
/**
* Update the user's password.
*
* #param \Laravel\Fortify\Contracts\UpdatesUserPasswords $updater
* #return void
*/
public function updatePassword(UpdatesUserPasswords $updater)
{
$this->resetErrorBag();
$updater->update(Auth::user(), $this->state);
$this->state = [
'current_password' => '',
'password' => '',
'password_confirmation' => '',
];
$this->emit('saved');
}
This all appears to work fine-ish. When I (the user) press [Change Password] Livewire sets the form inactive (to prevent the user from double-submitting the form), and when the response from Laravel/Livewire is received, the form is enabled again. And... well that's it.
The problem is that it doesn't matter what data I submit. If I enter all correct values, the password doesn't update! If I enter incorrect current_password, it doesn't error. If I submit the correct current_password with mismatching password and password_confirmation, I get the same "nothing happened" experience (as an end user). When I check the "network" tab on the browser's dev-tools, I get valid 200 responses each time without any obvious errors being reported in the detail. I know the PHP function is being invoked because if I put a dd($this) style debug in it, the JSON response throws back the Livewire object.
So the question I therefore have is the following...
How does the Fortify framework manage errors, and how am I supposed to catch them (in Livewire) to give the user some useful feedback?
Does the ErrorBag (which is reset in the first line of code) somehow get populated in the $updater->update() function?
Moreover, I copied (sorry, borrowed) this solution from Jetstream project. Does this also mean that the Jetstream interface is equally as unintuitive (from an end-user point of view)? Is there some higher-level concept that I've missed from the Jetstream project?
I was being stupid. The error bag is returned to the view, there just wasn't an outlet in the template to display the response. All I needed was a conditional label (or a span or a div) to display the field if the error exists.
<form wire:submit.prevent="updatePassword">
<input id="current-password" type="password" name="current_password" required="true" />
#error('current_password')
<label id="current-password-err" class="error" for="current-password">{{ $message }}</label>
#enderror
<input id="password" type="password" name="password" required="true" />
#error('password')
<label id="password-err" class="error" for="password">{{ $message }}</label>
#enderror
<input id="password-confirmation" type="password" name="password_confirmation" required="true" />
#error('password_confirmation')
<label id="password-confirmation-err" class="error" for="password-confirmation">{{ $message }}</label>
#enderror
<button type="submit">Change Password</button>
</form>

Browser-Based Uploads Using POST

I'm trying to create a client side uploads using POST with Signature Version 4 of AWS.
According to the documents
When i'm generating the signature on the server side I get an exact match with AWS signature mentioned in this example page.
However when I use it to upload the page I get this error:
SignatureDoesNotMatchThe request signature we calculated does not match the signature you provided. Check your key and signing method
This is the code I've used:
OpenSSL::HMAC.hexdigest('sha256', signing_key(string_to_sign), string_to_sign)
# step 2 in the aws documentation
def signing_key(encoded_policy)
# generate the correct date
date = extract_encoded_policy_date(encoded_policy)
date = time_adjust(date)
# encode all the fields by the algorithm
date_key = OpenSSL::HMAC.digest('sha256',"AWS4#{#secret_access_key}", date.strftime("%Y%m%d"))
date_region_key = OpenSSL::HMAC.digest('sha256',date_key, #region)
date_region_service_key = OpenSSL::HMAC.digest('sha256',date_region_key, #service)
signing_key = OpenSSL::HMAC.digest('sha256',date_region_service_key, 'aws4_request')
signing_key
end
def time_adjust(date)
time = Time.parse(date)
time += time.utc_offset
time.utc
end
After a little search in the net, i've encountered this article. Iv'e implemented this code and the upload succeeded.
signature = OpenSSL::HMAC.digest( OpenSSL::Digest::Digest.new('sha1'), #secret_access_key, string_to_sign)
Base64.encode64(signature).gsub("\n","")```
This is a small Demo for the client side code.
here is some literature I've found useful:
General description
Some code snippets from AWS
What is the differences between the two?
How can I get the first option to work and upload my files?
Is the example in the AWS page no longer valid?
After a research and comparing the AWS post example i found out that there were some redundant fields in the form that made AWS think i'm using SHA1.
After removing the AWSAccessKeyId field from the form and renaming some other fields I managed to make the AWS4 work.
This is the updated Demo
<form id="myForm" action="http://yourbucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
<input type="hidden" id="key" name="key" value="uploads/${filename}"/>
<input type="hidden" id="acl" name="acl" value="YOUR_ACL_OPTION"/>
<input type="hidden" name="success_action_redirect" value="http://google.com" />
<input type="hidden" id="type" name="Content-Type" value="MIME_TYPE"/>
<input type="hidden" name="x-amz-meta-uuid" value="14365123651274" />
<input type="hidden" name="X-Amz-Credential" value="YOUR_CREDENTIALS" />
<input type="hidden" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" />
<input type="hidden" id="date" name="X-Amz-Date" value="" />
<input type="hidden" name="x-amz-meta-tag" value="" />
<input type="hidden" id="policy" name="Policy" value="YOUR_POLICY_DOCUMENT_BASE64_ENCODED"/>
<input type="hidden" id="signature" name="X-Amz-Signature" value="YOUR_CALCULATED_SIGNATURE"/>
<input name="file" id="file" type="file"/>
<input id="btn_submit" class="btn btn-warning" type="submit" value="Upload File to S3">
</form>

Cross Domain Form Submission in Laravel

It is my first time to use laravel. I just want to ask a question regarding cross domain form submission best practice.
Let say I have simple HTML form in myfirstdomain.com/form
<form action="http://myseconddomain.com/insert/data/" method="POST">
<input name="fullname" type="text" placeholder="Enter your name" />
<input type="submit" value="submit">
</form>
And I have register "/insert/data" on my route file in other domain, let say myseconddomain.com :
Route::get('/insert/data', function()
{
$fullname = Input::get('fullname');
// Insert the name after this...
});
Is it safe to do that? I mean I'm using POST to submit form and using Route::get to fetch it?
Is there any other better option? I tried Route::post and get the MethodNotAllowed error instead.
Thank you

How to disable the validation of some fields in Joomla 3 registration

I'm building the website based on Joomla 3. I need to disable the validation of the fields: name, username, password1 (the second, because the first is password2) and email2 and use email1 as username (I installed the plugin Email for user authorization).
I have tried to remove these fields in file components/com_users/models/forms/registration.xml but the validation is still remaining. If I don't remove them but only change the rows required="true" to false for these fields the registration doesn't work at all and any user stored in the DB. How can I disable these fields?
It's not an easy workaround, and you will need some basic knowledge of Joomla and PHP, but I'll try to explain it to you as simple as i can.
>>> Creating view template override
First of all you will need to create your Registration view template override (to keep it Joomla update proof). To do so, create folder /templates/YOUT_TEMPLATE/html/com_users/registration and copy /components/com_users/views/registration/tmpl/default.php file there.
From now on you can modify registration output in your template folder.
>>> Modifying registration form output
By default Joomla takes all fields from form file /components/com_users/models/forms/registration.xml, where they are defined, and outputs them in a view. But if we don't want to use ALL the fields, we need to output fields manually.
My example code only output E-mail and Password fields for registration. Here's a sample code to do so: (default.php file)
<?php
defined('_JEXEC') or die;
JHtml::_('behavior.keepalive');
?>
<div class="grid_8" id="register_block">
<div class="content_block">
<h1>Registracija</h1>
<div class="login<?php echo $this->pageclass_sfx?>">
<form id="member-registration" action="<?php echo JRoute::_('index.php?option=com_users&task=registration2.register'); ?>" method="post" enctype="multipart/form-data">
<div>
<div class="login-fields">
<label id="jform_email1-lbl" for="jform_email1">E-mail:</label>
<input type="text" name="jform[email1]" id="jform_email1" value="" size="30">
</div>
<div class="login-fields">
<label id="jform_password1-lbl" for="jform_password1">Password:</label>
<input type="password" name="jform[password1]" id="jform_password1" value="" autocomplete="off" size="30">
</div>
<button type="submit" class="button"><?php echo JText::_('JREGISTER');?></button>
<input type="hidden" name="option" value="com_users" />
<input type="hidden" name="task" value="registration2.register" />
<?php echo JHtml::_('form.token');?>
</div>
</form>
</div>
</div>
</div>
Please note, that I've also replaced task value from registration.register to registration2.register, I did this to bypass some of validation rules using my own controller.
>>> Creating controller override
Locate file /components/com_users/controllers/registration.php and create a copy of it called registration2.php in same folder.
Open file registration2.php and change It's class name from UsersControllerRegistration to UsersControllerRegistration2
From now on Joomla registration form will use this class to create a new user.
Find a method called register and find this line:
$requestData = JRequest::getVar('jform', array(), 'post', 'array');
This is where Joomla get's registration form data. Add the following lines:
$requestData['name'] = $requestData['email1'];
$requestData['username'] = $requestData['email1'];
$requestData['email2'] = $requestData['email1'];
$requestData['password2'] = $requestData['password1'];
It will add missing registration info, and help you pass validation.
NOTE: This is a sample code, to show the main logic. If anyone has a better solution, I'd be more than happy to hear it.
Following same idea, a simpler solution might be just including hidden inputs with values in com_users\views\registration\tmpl\default.php above
<button type="submit" class="btn btn-primary validate"><?php echo JText::_('JREGISTER');?></button>
add
<input type="hidden" id="jform[username]" name="jform[username]" value="username" />
<input type="hidden" id="jform_name" name="jform[name]" value="name" />
It would pass the validation and you would no longer need to override controllers etc.

Resources