How to create an ftp user and allow write to the apache root directory with proper permissions

I do not recommend having a set up like this due to the multiple security vulnerabilities that it presents. There are much better and more secure ways to develop and deploy to a server. If you can use WebDAV, scp, etc.

If you still wanted to do this, there are some configurations you need to make, in order to have that ftp user upload files and have them be saved with the proper ownership and permissions, so that the webserver can still serve them.

This how-to is for Debian or any Debian derivative like Ubuntu. The set up would be almost identical for any other Linux distro, but you might have to use a different package manager instead of aptitude to install vftpd and the root of the web server might have a different path instead of /var/www.

1. Install vsftpd if you have not yet done so:

sudo apt-get install vsftpd

2. Edit /etc/vsftpd.conf. Here we will allow local users to ftp and set the default permissions (umask) for the files they upload. Make sure that the folloing is uncommended/added in the file:


anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=0002
anon_upload_enable=YES
anon_mkdir_write_enable=YES
file_open_mode=0777

For the mask to work properly (even without anonymous access) it seems necessary to set anon_upload_enable=YES and anon_mkdir_write_enable=YES. If these are not set, writing, reading and executing will not be allowed for groups or others on files uploaded via ftp (even though the standard privileges may be set for something else).

Here, file_open_mode sets the default setting of files. 777 makes it readable, writeable and executable for anyone. With local_umask set to 002, this gives you 775, as you requested.

Notice that local_umask defaults to 077, disabling groups and others to access files in any way (hence it is set here).

3. Restart the vsftpd to pick up the changes:

sudo service vsftpd restart

4. Create a local user that will be used for ftp (in our case we will call him ftpuser) and set the home directory to /var/www


sudo adduser ftpuser
sudo usermod -d /var/www -m ftpuser

5. Add the ftpuser to the www-data group

sudo usermod -a -G www-data ftpuser

6. Set the correct permissions on /var/www


sudo chgrp -R www-data /var/www
sudo chmod -R g+w /var/www

7. Make the directory and all directories below it “set GID”, so that all new files and directories created under /var/www are owned by the www-data group

sudo find /var/www -type d -exec chmod 2775 {} \;

8. Find all files in /var/www and add read and write permission for owner and group

sudo find /var/www -type f -exec chmod ug+rw {} \;
Wednesday, July 23rd, 2014 IT Security, Linux, Ubuntu No Comments

MapsInitializer.initialize no longer throws GooglePlayServicesNotAvailableException with the new google play services lib ver 15

I just updated the google play services lib to ver 15 to find out that MapsInitializer.initialize method no longer throws GooglePlayServicesNotAvailableException.

In the description of this method it now says:

Initializes the Google Maps Android API so that its classes are ready for use. If you are using MapFragment or MapView and have already obtained a (non-null) GoogleMap by calling getMap() on either of these classes, then it is not necessary to call this.

So, I guess if you have already called getMap and you have gotten a map object back, there is no need to call this any more.

Friday, February 14th, 2014 General 1 Comment

How to detect a user pan/touch/drag on Android Map v2

If you are impatient, you can skip directly to the solution.

The new implementation of the Android Map (v2) is great in many ways and their support for map fragments is awesome, but they fall a bit short in a couple of minor but very necessary implementations. That makes the maps API a bit incomplete.

I am referring in particular to the ability to distinguish between a user dragging (panning) the map, verses a programmatic move of the map.

That looks like a very basic need that a lot of Android programmers would face when dealing with the new map implementation. I have a number of apps, where I would like to update the map after the user has panned the map to a new location and I want to do that ONLY after they had stopped moving the map. I don’t want to trigger multiple updates while they are in the process of panning.

As you can deduce so far, there is no straight up way to implement this very basic behavior… or at least I could not find one. So, if you have found one, please let me know… I am only human and I might have missed something!

There are a couple of listeners implemented that kind of give you something to work with at a first glance, but they are both incomplete.

We have onCameraChangeListener, which gets called every time the map moves, zooms in/out or the camera angle changes, but it is completely useless in helping us implement the above needed behavior. It does not tell you in any way if the map was moved due to a user interaction or due to some other event triggering the map’s “camera change”. Furthermore, if you implement this listener you will notice that it gets triggered multiple times during a map panning. So, this makes it completely inefficient, especially when you are fetching data over the network all the time. The implementation of this listener could have been a bit more complete, if the only added a boolean value to the GoogleMap.OnCameraChangeListener indicating if the action was done by a human or not. Just like they implemented the SeekBar.OnSeekBarChangeListener.

Furthermore, you might think that this situation can be remedied with the map’s setOnMapClickListener, but you would be wrong, as you cannot use it in any way to distinguish between a touch down and a touch up events.

That finally leads us down the path of implementing this basic map behavioral need ourselves! I would like to think that Google does this to us, because they know we are better programmers than those stinking iOS dudes, who are used to getting anything they need handed on a platter of APIs:-) But may be I am wrong again…

So, a basic search led me to a couple of stackoverflow posts that try to tackle this issue:

How to handle onTouch event for map in Google Map API v2?
Google maps android api v2 – detect touch on map

But that sill did not completely solve my problem due to a couple of reasons. One is that they use an ugly static boolean variable to communicate back to the map activity if the map was touched or not. Furthermore they use that boolean in the setOnCameraChangeListener to decide whether to update the map or not, which flat out does not work. And the reason it does not work is because in most of the cases the setOnCameraChangeListener listener is triggered before the boolean value was updated, resulting in a failure of the code after that to execute.

So I took all this and made a few small but significant changes, namely using a custom interface to trigger the map to update at the right time. The TouchableWrapper class declares a UpdateMapAfterUserInterection interface, which is implemented by the Map Activity. That gives us a very fine control over the map events and what we want to do with them. Now a complete disclaimer… This all works very well, but it is a hacky way of doing things. Extending the map fragment, then putting a frame layout on top of if to intercept user interaction and then passing it over to the map activity just feels (and is) hacky. But it is the best solution I could find or think of for now. Please share if you have a better solution!

Here is the complete implementation:

UpdateMapAfterUserInterection class


public  class TouchableWrapper extends FrameLayout {

	private long lastTouched = 0;
	private static final long SCROLL_TIME = 200L; // 200 Milliseconds, but you can adjust that to your liking
	private UpdateMapAfterUserInterection updateMapAfterUserInterection;

	public TouchableWrapper(Context context) {
		super(context);
		// Force the host activity to implement the UpdateMapAfterUserInterection Interface
		try {
			updateMapAfterUserInterection = (ActivityMapv2) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " must implement UpdateMapAfterUserInterection");
        }
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			lastTouched = SystemClock.uptimeMillis();
			break;
		case MotionEvent.ACTION_UP:
			final long now = SystemClock.uptimeMillis();
			if (now - lastTouched > SCROLL_TIME) {
				// Update the map
				updateMapAfterUserInterection.onUpdateMapAfterUserInterection();
			}
			break;
		}
		return super.dispatchTouchEvent(ev);
	}

	// Map Activity must implement this interface
    public interface UpdateMapAfterUserInterection {
        public void onUpdateMapAfterUserInterection();
    }
}

MySupportMapFragment class


public class MySupportMapFragment extends SupportMapFragment{
	public View mOriginalContentView;
	public TouchableWrapper mTouchView;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
		mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
		mTouchView = new TouchableWrapper(getActivity());
		mTouchView.addView(mOriginalContentView);
		return mTouchView;
	}

	@Override
	public View getView() {
		return mOriginalContentView;
	}
}

The layout for the map activity


<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_below="@+id/buttonBar"
    class="com.myFactory.myApp.MySupportMapFragment"
    />

And finally the Map Activity


public class ActivityMapv2 extends FragmentActivity implements UpdateMapAfterUserInterection {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }

// Implement the interface method
public void onUpdateMapAfterUserInterection() {
		// TODO Update the map now
        }
 }
Tuesday, April 9th, 2013 Android, Eclipse, Java, Programming 25 Comments

Implementing Android GCM in a different package other than the main application package

There is something you need to be aware of if you are placing your GCM (Google Cloud Messaging, aka push notifications) service (the one extending from GCMBaseIntentService) in a package other than the main application package. The default implementation of the GCMBroadcastReceiver class, whcih is part of the GCM library assumes that your service is going to be in the main application package. If the service is in a different package though, then it will not be able to be started by the broadcast receiver and if you are debugging your app it will look like your app requests a Registration ID from the Google servers, but then everything dies off and you are not getting a response back.

What you need to do in this case is extend the GCMBroadcastReceiver class and override the getGCMIntentServiceClassName method to return the package name of the service and the service class name. So for example, if your service was called GCMIntentService in package com.mycompany.mainpackage.somepackage, you would return: “com.mycompany.mainpackage.somepackage.GCMIntentService”. Here is an example of the extanded GCMBroadcastReceiver class:


public class GCMMyBoadcastReceiver extends GCMBroadcastReceiver {
	protected String getGCMIntentServiceClassName(Context contest) {
		return "com.mycompany.mainpackage.somepackage.GCMIntentService";
	}
}

Also, do not forget to update your manifest file to make sure that the new extended broadcast receiver is used:


<receiver android:name="com.mycompany.mainpackage.somepackage.GCMMyBoadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
	<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="com.mycompany.mainpackage" />
   </intent-filter>
</receiver>

This little detail wasted a coule of hours of my time trying to figure out what I did wrong. Unfortunatly this detial is not well documented (not even mentioned) in their GCM implementation tutorial.

Monday, November 26th, 2012 Android, Eclipse, Java, Programming 1 Comment

Quick and easy way to remove all single line (//) comments in Eclipse

I had to quickly remove single line comments from an Android project in Eclipse. I could not find any built in feature in Eclipse to do that. So I resorted to a simple regular expression:

(//[^\n]*)

This simple regex selects all the strings that begin with “//” and end with a new line. So all you have to do is use it in the find and replace option for a file or to apply to the whole project or multiple files do Search -> File. Also, make sure to select the “regular expression” check box.

This is something I did very quickly… so be careful since it might pick up some urls as well… like anything after the “//” part in “http://mysite.com/page.php”.

Wednesday, November 7th, 2012 Android, C++, Eclipse, Java, Programming 1 Comment

Search

 

Archive

October 2014
M T W T F S S
« Jul    
 12345
6789101112
13141516171819
20212223242526
2728293031  

Other