Problems with setting up foreign file repository - mediawiki

I installed a MediaWiki instance on my Ubuntu box which is working fine. I used us instant commons but this caused a huge delay on rendering pages.
I therefore decided to implement my own MediaWiki Commons instance as well in order to store images I use for my main wiki. This works fine too.
The problem I am having is with configuring "$wgForeignFileRepos" and in particular the parameter "apibase". Whenever I upload a new image along with description etc. and create a new article on my main wiki instance, I have to change "apibase" path.
For example, I have a starting configuration of:
$wgForeignFileRepos[] = array(
'class' => 'ForeignAPIRepo',
'name' => 'privateCommons',
'apibase' => 'http://ubuntu/commonsmediawiki/api.php',
'hashLevels' => 2,
'fetchDescription' => true,
'descriptionCacheExpiry' => 432000,
'apiThumbCacheExpiry' => 864000
);
Now I add a new image including description to commons, followed by a new article using the just added image. However, the image does not show up.
I now have to change "apibase" to
'apibase' => 'http://localhost/commonsmediawiki/api.php'
to make the image appear. Repeating the process by adding a new image and new article the image does not show again.
Again I have to change "apibase" to any of:
'apibase' => '//localhost/commonsmediawiki/api.php'
'apibase' => '//ubuntu/commonsmediawiki/api.php'
'apibase' => 'http://ubuntu/commonsmediawiki/api.php'
By doing that the second article displays the most recent image after purging but when I go back to the previously added article the image is gone again.
By the way, I am running the same version of MediaWiki that is used by Wikipedia (1.26wmf4). My Ubuntu version is pretty up to date (14.04).
I should also mention that both wikis share the images folder which should not be a problem because images will never be stored in both wikis. The two wikis do neither share any tables.
I also tried to use "ForeignDBRepo" which did not work at all saying that the images could not be found which I do not understand either.
I have not the slightest clue how to remedy this very annoying behaviour. So any suggestion would be very much appreciated.
Thank you very much

From your description, the only URL which ever worked was
'apibase' => 'http://localhost/commonsmediawiki/api.php'
so please use that. It must be an URL that the server can contact. A fake domain like //ubuntu/ would need some DNS trick on your end, which you didn't mention doing.
I suspect you didn't set up cache correctly, so you may try and disable caching for this feature:
'descriptionCacheExpiry' => 0,
'apiThumbCacheExpiry' => 0
and let us know how it worked.

Related

I want to get the backend url from frontend without using hardcoded URLs yii2

'urlManagerBackend' => [
'class' => 'yii\web\urlManager',
'baseUrl' => 'http://backend.test',
'enablePrettyUrl' => true,
'showScriptName' => true,
],
then I want to display the image saved under uploads directory
<img src="<?= Yii::$app->urlManagerBackend->baseUrl; ?>/uploads/logo.jpg>
the problem is this url must not be hardcode like this:
'baseUrl' => 'http://backend.test',
The only way how to dynamically determine the domain of the other application (for example the backend from your frontend) would be by parsing the web server's configuration files.
The domain for current application (the one you can get with Url::base(true)) is determined from the request headers or variables set by web server. But those are available only for current application, not for any other application even if they are part of same project.
If you want to parse web server's configuration files than you will have to face three major challenges:
Different web servers have different syntax for configuration files.
Configuration files might be located anywhere.
You might not have access rights to read the configuration files.
So it might be better to try to think about some workaround instead of insisting on determining the domain dynamically.
Make a deploy script that would ask for the backend domain. The one who will be deploying your application on production servers will know the domain for the backend application and can enter it during deployment process. The deploy script will then set the entered backend domain in your configuration files.
Make a page in backend that must be visited before accessing the frontend application. You can determine the domain for backend when the page in backend is visited then set that domain in frontend configuration files. If the frontend is accessed before the domain for backend is set you will only display the notice that the backend page must be accessed first.
In the config folder there should be a file called params.php. If you have something like this
<?php
return [
'adminEmail' => 'admin#example.com',
'baseUrl' => 'http://backend.test',
];
You can use it in your code like this
<img src="<?= Yii::$app->params['baseUrl']; ?>/uploads/logo.jpg>
Then when you move to live, you just need to edit the params.php file.
Too long comment so I need to put it here.
But I'm just wondering in which case that makes sense, except if you are creating web applications, sites, ..., through your application, which I doubt you do.
You know your local domain (use local environment and put urls).
You will know your dev domain (use dev environment and put urls).
You will know your production domain (use prod environment and put urls).
You can also have multiple applications inside yii2 project, so for example,
10 applications across 3 envs, that is 30 urls which you will enter in you configs.
Can you please tell me, how you will access your app if url is dynamically determined -> without using anything else except Yii?
What is your step? You are typing in your browser what? Then we can proceed. Maybe we misunderstand each other.
urlManagerBackend' => [
'class' => 'yii\web\urlManager',
'baseUrl' => 'http://backend.test',
'enablePrettyUrl' => true,
'showScriptName' => true,
]
If you are wondering you can also have multiple urlManagerBackend components across Yii2 environments. Just like with params. Add it on multiple corresponding places at config. So in specific environment you place at same file only key => values which you need to override.
You could simply use Assets and Aliases for this:
If you have a backup/web/uploads/ folder in which you save images uploaded via your backend and you'd like to display those images on your frontend.
Create a new asset file in your frontend/assets/, let's call it BackendAsset.php:
<?php
namespace frontend\assets;
use yii\web\AssetBundle;
class BackendAsset extends AssetBundle {
public $sourcePath = '#backend/web/uploads';
}
where $sourcePath is the backend-folder (source) you'd like to access on the frontend. The #backend alias is predefined in the advanced template, so we'll use it.
Now in our view we can simply use the BackendAsset:
<?php
use frontend\assets\BackendAsset;
$backend = BackendAsset::register($this);
?>
and now we can easily display a file, let's say backend/web/uploads/somefile.jpg:
<img src="<?= $backend->baseUrl . '/somefile.jpg' ?>" >
NOTE: Using the asset in this way copies all the files from the backend/web/uploads to an asset folder in the frontend. To prevent that, you can tell your application not to copy the files, but to link to them (creating SymLinks) instead, unsing linkAssets (yii2 docu):
In your app configuration (in this case frontend/config/main.php), set the linkAssets parameter to TRUE:
'components' => [
'assetManager' => [
'linkAssets' => true,
]
]
I solve this problem by saving the full url in the database.
What about putting a reverseproxy (e.g. nginx) in front of the frontend-server?
Could be configured like:
http://frontend/backend/* -> forwards everyhing to the backend service, the rest will still go to the frontend server.
The configuration (in this case the location of the backend server) of this reverseproxy can be changed any time (also after deployment).
Could that be a viable scenario?

Chrome Web Store In-App Payments: Errors getting SKUs

I'm trying to get the SKUs available for a freemium Chrome Extension I'm developing.
I'm following all of the documentation here:
https://developer.chrome.com/webstore/payments-iap
...and I'm using the provided buy.js file, but it doesn't seem to work and the returned error messages are useless: "INVALID_RESPONSE_ERROR"
My code:
google.payments.inapp.getSkuDetails({
parameters: {env: 'prod'},
success: (r) => {
console.log(r);
},
failure: (err) => {
console.log(err);
},
});
Thoughts:
- Am I missing some permission in my manifest? I don't see any mention that it needs any additional ones.
Other StackOverflow questions have mentioned needing to proxy due to region issues. I'm in the states, shouldn't be an issue.
I've tried the above from both an options page and a popup - does it need to happen in a background page?
I'm pretty baffled. Any help is appreciated!
Thanks.
Updates:
The above works when released (in prod), but not locally
In prod you cannot buy your own thing (heads-up). It'll give you some stupid, meaningless error, but won't tell you that.
Still can't get this to work locally which means I have to test in prod.
If you need this to work locally, you must set the 'key' in your manifest.json file. When you reload it, it will show the same ID as the loaded extension from production.
Here are instructions on how to get the relevant key
If you debugging your extension in unpacked mode, you may need to set production "key" in your manifest.

Setting database parameters in Zend 3

I'm a serious newbie as it comes to Zend and I'm now forced to work with Zend 3 (and learn it). Fellow developers have done parts of the application and now I'm cloning it on my side.
I receive "Database not selected" in the error log - I have set database.local.php and I think they've set everything else. Credentials are correct.
I'm working on Windows.
Is there anything else I could be missing as it comes to settings or database connection?
Thanks. I will provide any additional info if needed.
As we're dealing with both Zend Framework AND a configuration issue, for your next question, please make sure to also include file paths and such.
I'm proceeding with this answer under the assumption that you've created your file here: /config/database.local.php.
Note: using ZF3 myself, I, of course, tried to find your error message "Database not selected", however it comes back with no results. Make sure you copy and paste error messages so users of any framework, cms or another system can more easily help you out.
You'll find the problem you're facing in the application.config.php file (in the /config folder. In here you'll find the following config:
// Retrieve list of modules used in this application.
'modules' => require __DIR__ . '/modules.config.php',
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => [
// ... other config
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively override configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => [
realpath(__DIR__) . '/autoload/{{,*.}global,{,*.}local,{,*.}deploy,{,*.}development}.php',
],
// ... other config
],
Any of the *.local.php or *.global.php config files should be placed in /config/autoload/. Though, if you modify the above config, you could technically place it wherever you'd like.
Next, make sure you have the Zend\Db module enabled in your configuration. Open up the /config/modules.config.php file and make sure Zend\Db is in the list of Zend modules to be loaded in.
Lastly, you have not provided the config you used, so I'm assuming you made a mistake there. Use something like the config below in your /config/autoload/database.local.php file. Technically you could split this over 2 files; a global and a local file. Local files are (/should) not be committed into version control history and as such can contain usernames and passwords. Any other config, such as using Pdo for a driver could go into global config.
'db' => [
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf3;hostname=localhost',
'username' => 'root',
'password' => 'root',
'driver_options' => [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
],
],

Masking an image's real URL in Rails

I'm creating an incredibly basic photo sharing app in Rails that displays albums from the local filesystem.
For example -
/path/to/pictures
|
|-> 2003_college_graduation
|-> 2002_miami_spring_break
However, anyone can take a look at the HTML source and get the absolute path to the image -
my.server.com/path/to/pictures/2003_college_graduation/IMG_0001.JPG
And with a little guesswork, anyone could navigate to other images on the server, even ones they don't have permission to.
Is there any way to "mask" the URL here?
One potential solution is to hash each filepath into a UUID and store the mappings in mysql table. Then when they request the URL with that hash I can look it up in the table and pull the correct image. But that makes the URL looks messy and creates a problem if the URL ever changes (because the hash will change).
Are there any libraries or other workarounds to mask the real path to a file?
Thanks!
You could use a url minifier (take your pick) and use that link. They'd still be able to see the original source if they followed it, but it would get it out of the html file.
What you're trying to achieve here is a security through obscurity, which isn't going to work in the end. One can get aware of the scrambled URLs from any other source and still have access to the pics he should not be seeing.
The real solution is to actually control access to the files. It is a pretty common problem with a pretty common solution. In order to force access control you have to invoke a Rails controller action before serving the file and verify the credentials, and then, if the credentials are valid, serve the actual file.
It could be like this in the controller:
class PhotoController < ApplicationController
def photo
if user_has_access?(params[:album], params[:photo])
# be *very* careful here to ensure that user_has_access? really validates
# album and photo access, otherwise, there's a chance of you letting a malicious
# user to get any file from your system by feeding in certain params[:album]
# and params[:photo]
send_file(File.join('/path/to/albums', params[:album], "#{params[:photo]}.jpg"), type: 'image/jpeg', disposition: 'inline')
else
render(file: File.join(Rails.root, 'public/403.html'), status: 403, layout: false)
end
end
private
def user_has_access?(album, photo)
# validate that the current user has access and return true, if he does,
# and false if not
end
end
And then in your routes file:
get '/photos/:album/:photo.jpg' => 'photo#photo', as: album_photo
And then in your views:
<%= image_tag album_photo_path('album', 'photo') %>
What's good about send_file is that it simply serves the file out of Rails in development mode, but in production it can be configured to offload it to the actual webserver to keep the performance of your Rails code optimal.
Hope that gives a basic idea of what it might be and helps a bit!

503 (Service Unavailable) when trying to Create File to Google Drive

We've been getting a 503 error since yesterday when making this call:
result = session.execute(
api_method: drive.files.insert,
body_object: file,
media: media,
parameters: {'uploadType' => 'multipart', 'alt' => 'json'}
)
We have 3 set of keys - one each for our development, staging, and production environments.
The above call works without issue in our development environment, but fails 100% of the time in both staging and production environments
Based on the gists shared privately, it looks like the issue is the user agent header. I was able to reproduce by setting the UA similar to that one. I haven't been able to narrow it down to a particular issue with the UA, just that it doesn't work. Other multi-line strings work, and other chars seem fine if I replace the newlines.
Anyway, easiest thing to do is set :application_name with a different value that what you're using now.