parse.com delete a user account including related objects - ios

I know that to delete a Parse user, we have to call the "delete" method on the authenticated Parse User object. However, that only deletes the user in the User table, but not all data related to that user in other tables. Is there a way to trigger this automatically or do we have to implement this manually via some code in the "before_save" or "after_save"?
Also, should I log out the user after deleting his account?

You can implement it in before_save or after_save, but I would go with a hardcoded version of this. It strongly depends on your data structure, but generally, you would have to query for all the objects related to a user and then delete them separately (in background).
I would also log out the user, because due to caching, the app often doesn't realise that the user doesn't exist anymore, so I would go for logging the user out from Parse (even if that logout may fail because there is no user to logout anymore) and log him out of the app by showing him the login screen or whatever you're usually doing.
You see, deleting every information related to a user is a quite time and resource expensive task to do, so usually one simply deletes the user and his private information, and leaves the rest (for example in a messenger app, you would not delete the messages, as you want the other users still to be able to see what they wrote to the - now deleted - user).

Related

Link existing PFUser Facebook and Twitter with Parse on iOS

In my iOS application on the initial launch user can sign in with 3 different ways: email/pass, Facebook or Twitter. Registering with each of them will cause to create 3 different users.
Later in my app user should have the possibility to link accounts. For example, if he signed in with email/pass, then he should be able to link Facebook and Twitter.
Parse native -linkInBackground works great in case we have only one user, which is email/pass. But if we will already have Facebook or Twitter account created, the Parse SDK will reply with error, saying that this account is already linked to the social.
At first I thought that I've figured out the workaround:
Save the old user data
Delete the old user
Sign in (not link) with the social (say, Facebook)
Fill all the data from the saved user to the new one.
Everything went well with one social, but it appeared that the "authData" field, which is very important in my approach, is not contained in the [PFUser currentUser]. And so despite the fact that all other data is transferred successfully, the authData is not transferred, so that we don't have authentication data of the old user.
The question is: Is there a way to get authData from Parse, or is there any "legal" way to achieve my initial goal of merging (linking) two (three) users?
No, you can not access the auth data, just like you can't access the password when the user authenticates directly with email/pass. This is a security requirement and will not change.
Ideally you should add some logic which checks if the new user should be created or if a user with the specified details (probably email address) already exists. If it does then you can reject the new user creation and return a suggestion as to how the user should login.
Well, I've got it working in a bit different way than I wanted, but looks like it's a quite stable solution.
I've created a custom Parse Class, called, say, MyUser. This class has several fields, like: facebookUser, twitterUser, regularUser, anyOtherSocialUserYouWant. Each of them is a pointer to the _User class.
Now if we are signed as, for example, a regular user, the regular user is created. The same happens with the rest like Twitter or Facebook. By signing in with three different socials we will get three different parse users. That's okay.
Next somewhere in the app, user will press "Link to Facebook" button. We need to save the current user. Next we will make a query for both users if there is a MyClass object with pointers to one of those two users (first is the current user, the second is the new user after sign in). If there is no such MyClass object, we will create one and fill in two fields: regularUser and FacebookUser.
Later if user will try to link to Twitter, we will do the same, and the query will return existing MyClass object, which will have two fields with pointers to regular and Facebook users. We will just add a pointer to the newly signed in Twitter user to that MyClass object.
The only trick is with the data, which should be common for all of the users. It is easy enough with the appropriate query. We will need to do two queries (or one "OR" query, but looks like "OR" query is not working with pointers): first query for required object with "user" field of current user, and the second query (inner query) is for objects with "linkedUser" equal to current MyClass object.
And thus to maintain objects we will need to have two fields on each object: "user" and "linkedUser". First field will be used always, and the second field will be used only after linking.
And yes, after MyClass user is created you will need to check if objects for current user and newly registered user has this fields "linkedUser" and fill it with the MyClass pointer in case of that field is empty.
Hope this will help someone.
P.S.: Dear Parse.com developers, I really appreciate your work, but you should really think about creating the kind of mechanism to merge users.

Parse iOS Destroy Button (Password Validation Dependent) Client side

I'm starting to create a lot more features for users in my app. I've run into some app structure issues.
lets say I have User Fooman
Fooman wants to edit his account, delete some objects(wall posts), update his friends list etc.
Fooman is logged in to do all of these. But footman isn't the one using the device at the moment. It's fooman son (foobaby). Foobaby decides to just be a son and delete things erroneously. I have an option for users to delete their account client side. I present them an alert view to confirm that's the choice they meant to select. After they confirm that, another view populates with a 'Destroy' (or delete button) that will delete the User, plus all relations/pointers/data connected to it. Before that button is enabled a password validation check is required so it's not done by a foobaby. However, with Parse, this has proved to be problematic client side. I don't use cloud functions because, well, simply put, at this point in time my app is one platform and doesn't really need to use it.
Is there any workaround anyone has come up with that's quick/efficient, API friendly for validating a textField.text with the [PFUser currentUser].password whilst maintaining security of course.
I code in Objective-C :)
Note: I have tried numerous things but nothing seems to work outside of trying to log them in against the user input (UITextField), which doesn't feel like the right way to do it in my opinion.
I think it's an unusual requirement. The idea of a logged-in user is that the app trusts the user. A persisted logged-in user on the device means that the app trusts whomever is holding the device. So FooBaby is trusted, because FooDad let him hold the phone.
Some apps put up a barrier to establish thoughtfulness, like the Parse data browser requiring that you type the name of a class before you drop it. But this establishes thoughtfulness, not trust. (For a child, I guess it also establishes minimal competence, in case FooBaby knows how to press buttons, but not how to spell).
Otherwise, I can't think of how to do it besides requiring a login, which you mentioned you find unappealing (though you didn't say why). Excluding that, I don't think there's a way to do it without spoiling security with something like keeping an in-the-clear copy of the password.

How do I save temporary data for anonymous users in Rails

For example, if an anonymous user clicks on "like" button, he will be redirected to a signin page; the user can choose either to sign up or sign in, in either way server will remember his action so user does not to click again. The data should be destroyed 10 minutes after it's created.
How do I implement this?
You basically just want to serialize a list of things to be done once they create an account. You could store this in a session, a persistent cache like memcached (though you aren't guaranteed persistence), or a custom model/table. There's not really any single accepted way to do this in Rails, so it's left up to you as to how you implement it.
What you could do, if you want to stick to the Rails way of doing things, is to set a transient flag on a record, then save it. Once the user registers, you can remove the transient flag. Run a cron job that destroys all transient records older than 10 minutes, and all your before_destroy callbacks should be run to let you roll back any state changes they caused. That's a "heavy" solution, but it's easy to implement and lets you leverage Rails' models easily.
I would use sessions to store the temporary data.

How to automatically maintain a table of users that have been authenticated by IIS 7.0 using Windows Authentication

I want to build and maintain a table of users. All users that access the ASP.NET MVC site are authenticated via Windows Authentication so they're bound to have a unique username. I'm grabbing the user name from:
System.Web.HttpContext.Current.User.Identity.Name
I feel like I could go two ways with this.
Anytime the user table or any tables that references the user table are accessed, I could add the user if it doesn't exist. I'm worried this might be very error prone if user's existance isn't checked.
Anytime the user visits any page on the site, check if that user exists in the db and if they don't exist, add the user. This may have a lot of overhead as it'll be checked every page change.
I'd like to hear which of these is the better solution and also how to implement them.
I think a better way would be something similar to the option two.
Anytime a user visits a page, check a session variable to see if that user was checked against the DB. If the session variable is not there, check if that user exists in the DB, add the user to your table if necessary, then set the session variable.
That way you don't have to hit the DB on every request.

Allow users to remove their account

I am developing a gallery which allows users to post photos, comments, vote and do many other tasks.
Now I think that it is correct to allow users to unsubscribe and remove all their data if they want to. However it is difficult to allow such a thing because you run the risk to break your application (e.g. what should I do when a comment has many replies? what should I do with pages that have many revisions by different users?).
Photos can be easily removed, but for other data (i.e. comments, revisions...) I thought that there are three possibilities:
assign it to the admin
assign it to a user called "removed-user"
mantain the current associations (i.e. the user ID) and only rename user's data (e.g. assign a new username such as "removed-user-24" and a non-existent e-mail such as "noreply-removed-user-24#mysite.com"
What are the best practices to follow when we allow users to remove their accounts? How do you implement them (particularly in Rails)?
I've typically solved this type of problem by having an active flag on user, and simply setting active to false when the user is deleted. That way I maintain referential integrity throughout the system even if a user is "deleted". In the business layer I always validate a user is active before allowing them to perform operations. I also filter inactive users when retrieving data.
The usual thing to do is instead of deleting them from a database, add a boolean flag field and have it be true for valid users and false for invalid users. You will have to add code to filter on the flag. You should also remove all relevant data from the user that you can. The primary purpose of this flag is to keep the links intact. It is a variant of the renaming the user's data, but the flag will be easier to check.
Ideally in a system you would not want to "hard delete" data. The best way I know of and that we have implemented in past is "soft delete". Maintain a status column in all your data tables which ideally refers to the fact whether the row is active or not. Any row when created is "Active" by default; however as entries are deleted; they are made inactive.
All select queries which display data on screen filter results for only "active records". This way you get following advantages:
1. Data Recovery is possible.
2. You can have a scheduled task on database level, which can take care of hard deletes of once in a way; if really needed. (Like a SQL procedure or something)
3. You can have an admin screen to be able to decide which accounts, entries etc you'd really want to mark for deletion
4. A temperory disabling of account can also be implemented with same solution.
In prod environments where I have worked on, a hard delete is a strict No-No. Infact audits are maintained for deletes also. But if application is really small; it'd be upto user.
I would still suggest a "virtual delete" or a "soft delete" with periodic cleanup on db level; which will be faster efficient and optimized way of cleaning up.
I generally don't like to delete anything and instead opt to mark records as deleted/unpublished using states (with AASM i.e. acts as state machine).
I prefer states and events to just using flags as you can use events to update attributes and send emails etc. in one foul swoop. Then check states to decide what to do later on.
HTH.
I would recommend putting in a delete date field that contains the date/time the user unsubscribed - not only to the user record, but to all information related to that user. The app should check the field prior to displaying anything. You can then run a hard delete for all records 30 days (your choice of time) after the delete date. This will allow the information not to be shown (you will probably need to update the app in a few places), time to allow the user to re-subscribe (accidental or rethinking) and a scheduled process to delete old data. I would remove ALL information about the member and any related comments about the member or their prior published data (photos, etc.)
I am sure it changing lot since update with Data Protection and GDPR, etc.
the reason I found this page as I was looking for advice because of new Apply policy on account deletion requirements extended https://developer.apple.com/news/?id=i71db0mv
We are using Ruby on Rails right now. Your answers seem a little outdated? or not or still useful right now
I was thinking something like that
create a new table “old_user_table” with old user_id , First name, Second name, email, and booking slug.
It will allow keep all users who did previous booking. And deleted their user ID in the app. We need to keep all records for booking for audit purpose in the last 5 years in the app.
the user setup with this app, the user but never booking, then the user will not transfer to “old_user_table” cos the user never booking.
Does it make sense? something like that?

Resources