Making a username unique for database insertion - coldfusion

I am inserting unique names into a database table that have been submitted by users as their username.
When a name is submitted via a form, my ColdFusion code checks the database to see if that name already exists. If it does exist then it makes it the username unique by adding a sequential number to it.
My issue is that while checking the database for a name conflict is easy enough, I also don't want the name to conflict with the name of any folder, .cfm file, or .html file in my site.
At the moment I am using a simple ListFindNoCase('folder1,folder2,folderN', username) function to check for conflicts but this is done manually. Whenever I add a new file or folder to the site I have to add it to this list. Its not a good way to do it.
How can I get a list of all the contents in my site and make it into a delimited list and then do the ListFindNoCase() function to check if the username is in that list of contents? Is this even a pragmatic way to go about it?

Turn your 'folder1,folder2,folderN' into a getter function that returns a list of folders.
Then you can decide how to gather that list of folders.
Here are several ways I can think of:
some global config file, or if you use coldbox, use coldbox's config.cfc settings
do a directoryList() and figure it out dynamically, and optionally cache the result
store the forbidden folder names in DB and check against the DB using sql

Related

Use validation to prevent duplicate file _name_ being uploaded

How can I detect that the name of a file that a user has provided for upload (via a django.forms.ModelForm using a FileField field) is a duplicate of one that exists, and thus decide to fail validation on the form?
I'm finding this particularly challenging, because from within the form, I don't see how I can find out what the value of upload_to is for this FileField, so I can't go looking myself in the file system to see if that file is there already.
As i see it you have 2 options:
Set a value in your settings.py to hold your 'upload_to' and then use it to check when you are validating.
Something like this to verify would work (you need to change your upload_to ofc):
from django.conf import settings
if settings.UPLOAD_TO:
# Do something
Issue with that is that you can't have subfolders or anything complex there.
A second option would be, as mentioned in your comments, to add a new column to your model that holds a hash for your file. This approach should work better. As someone mentioned in your comments, to avoid uploading a big file, checking, failing, uploading another big file, etc, you can try to hash it in the client and verify it via ajax first (you will verify it again in the server, but this can make things go faster for your users).
Older question, but Django 1.11 now supports the unique option on FileField. Set unique=True on your field declaration on your model.
It shouldn't matter what you are setting upload_to to. The file name will still be stored in the database.
Changed in Django 1.11:
In older versions, unique=True can’t be used on FileField.
https://docs.djangoproject.com/en/1.11/ref/models/fields/#unique

In Django, how can I tell my project to read/write in distinct log directories at runtime?

I am working on a django project that, along with having a database for its models and relations, writes to a log directory called activity_logs outside of the project directory to keep track of formatted user activities, one file for each user. This is an alternative file-structure-based solution to having a database table carry this information along, because this offloads some storage from the DB and is relatively easy to format and express such activities. Perhaps some of you may recommend storing this kind of data in the database, which is fine, but I still believe there is question from all of this that I need help answering.
This django project has multiple apps that have an extensive test suite, one for each app. Additionally, there is a logging.py file that encapsulates the logging functionality (writing/reading activities to/from log files), and so both the test cases within the test suites as well as the view functions (and various other utility functions) all utilize these logging functions in order to store these user activities and retrieve them based on model relationships to emulate a user notification system. Since the logging module takes care of this logging, it needs to know where to write to, and so we have a directory structure called activity_logs to which it writes user log files, creating one for a new user and deleting one for a user removed from the database. One of the newest changes we would like to make in this project is to create a separate logging directory for testing this logging functionality, something like test_activity_logs, so that it would never be confused when writing to the test directory for test users or the regular activity log directory for real users.
My problem is this: at runtime, how can I tell the system, at whichever startpoint of execution (whether it be from a view function call through the django test Client object, a test case, an actual HTTPrequest made via a URL, etc.), when to look inside the activity_logs or the test_activity_logs directory? It solely depends on whether I am generating new information for a real user or a test user, but a User is a User in our system, and I'm facing some trouble trying to tell these functions that call some logging functions to write to the test log directory vs. the regular one. For example, one approach I am trying is to pass a keyword argument (kwarg) to the logging functions so that they can be made aware of which directory to read/write to/from, like so:
self.assertTrue(activity_has_been_logged(ACTIVITY_ACCOUNT_CREATED, user.get_profile(), use_test_activity_log_directory=True) == True)
the kwarg called use_test_activity_log_directory=True will tell the logging function called activity_has_been_logged to read the test activity log directory. Unfortunately, apart from being a little inflexible (but tolerable), this doesn't solve the situation where the django test client object sends a GET or POST request via a URL to a view function that writes activities to log files:
response = client.post(propose_match_url, post) #Can't write to test_log_directory if by default it writes to regular directory!
How do I let the client pass on this kwarg to those view functions? I think that it should totally be possible to do this, but I'm not sure if fiddling with these kwargs is the best way, or maybe create a global variable in the project settings file, but maybe that might cause some trouble with race conditions with a shared mutable variable.
Your help would be great. Thanks in advance!
So I just solved this problem. The logging file hosting all logging functionality is really the only place that needs to know where to look (either test_activity_logs or activity_logs), since all other components will invoke functions from the logging module to write/read to/from these directories. I gave an additional field to the model class of the UserProfile class called is_test that is a boolean field to determine whether to look in the test_activity_logs if is_test=True, or activity_logs if is_test=False. That way, the logging module needs only to check the input parameter of type UserProfile and its new field to determine where to perform its logging functionalities. Problem solved!
Check out daemontools if you're on a *nix box or launchd on OS X. Both can make sure your Django instance stays running in whatever mode you prefer (daemontools has a few more options for that) and can isolate a directory for logging stdout/stderr.
You can set environment variables for each instance to help other log files and temporary files know where to be created, which you then get from os.environment or simply use the current working directory as a base if using daemontools.
The directory is automatically created for you using daemontools.

How can I find the InternetRegistry User Key or Parent Registry Key

I have a BHO which on the first run is gathering activation information and storing this in the registry.
(I think) due to IE's permission's I am only able to store this in the registry branch
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\InternetRegistry\REGISTRY\USER\S-0-0-00-000000000-000000000-000000000-0000\Software\MyBHO\MyKey
Where S-0-0-00-000000000-000000000-000000000-0000 is a unique key for each user.
Which is fine using RegCreateKey() with "Software\MyBHO\MyKey". It's all created and running lovely. It determines where in space to store the Key with no problems.
The Problem:
When I carry out an uninstall I want to remove this key and as this is run outside of IE I have no way to determine where that key is / what the user string is.
Options I have in mind:
Option 1 (Ideal)
Find out this user string first to then build a new path for the key I wish to remove and remove it. How?
Option 2
At the point of activation store the path to the key in another registry value that can be accessed. Then read, and delete both (Which seems a bit backwards and probably wont work due to the access restrictions of the BHO on the registry (Thus it being written there in the first place))
Do you know if there is any way to find this User key or even how to find the parent dir.
Edit Upon continued research I've found that the thing I'm referring to as "user key" is the current Users "SID". Maybe this will yield me better results.
Call GetUserName to get the user name, and LookupAccountName to get his SID.
ConvertSidToStringSid is a useful utility function to format a SID as a S-1-5-32-00000000-00000000-00000000-00000000-0000 string
If you really want to write per-user data to the registry, use IEGetWriteableHKCU().
In general there is no good way to remove per-user data at uninstall. For example, what if you install as user A and the uninstall as user B? Are you going to go find all of them and delete them? Just leave the turds behind.
Alternatively you could consider using a different data store. Do you really need the registry? Can you store this data in a file? What about Web Storage?

Mediawiki mass user delete/merge/block

I have 500 or so spambots and about 5 actual registered users on my wiki. I have used nuke to delete their pages but they just keep reposting. I have spambot registration under control using reCaptcha. Now, I just need a way to delete/block/merge about 500 users at once.
You could just delete the accounts from the user table manually, or at least disable their authentication info with a query such as:
UPDATE /*_*/user SET
user_password = '',
user_newpassword = '',
user_email = '',
user_token = ''
WHERE
/* condition to select the users you want to nuke */
(Replace /*_*/ with your $wgDBprefix, if any. Oh, and do make a backup first.)
Wiping out the user_password and user_newpassword fields prevents the user from logging in. Also wiping out user_email prevents them from requesting a new password via email, and wiping out user_token drops any active sessions they may have.
Update: Since I first posted this, I've had further experience of cleaning up large numbers of spam users and content from a MediaWiki installation. I've documented the method I used (which basically involves first deleting the users from the database, then wiping out up all the now-orphaned revisions, and finally running rebuildall.php to fix the link tables) in this answer on Webmasters Stack Exchange.
Alternatively, you might also find Extension:RegexBlock useful:
"RegexBlock is an extension that adds special page with the interface for blocking, viewing and unblocking user names and IP addresses using regular expressions."
There are risks involved in applying the solution in the accepted answer. The approach may damage your database! It incompletely removes users, doing nothing to preserve referential integrity, and will almost certainly cause display errors.
Here a much better solution is presented (a prerequisite is that you have installed the User merge extension):
I have a little awkward way to accomplish the bulk merge through a
work-around. Hope someone would find it useful! (Must have a little
string concatenation skills in spreadsheets; or one may use a python
or similar script; or use a text editor with bulk replacement
features)
Prepare a list of all SPAMuserIDs, store them in a spreadsheet or textfile. The list may be
prepared from the user creation logs. If you do have the
dB access, the Wiki_user table can be imported into a local list.
The post method used for submitting the Merge & Delete User form (by clicking the button) should be converted to a get method. This
will get us a long URL. See the second comment (by Matthew Simoneau)
dated 13/Jan/2009) at
http://www.mathworks.com/matlabcentral/newsreader/view_thread/242300
for the method.
The resulting URL string should be something like below:
http: //(Your Wiki domain)/Special:UserMerge?olduser=(OldUserNameHere)&newuser=(NewUserNameHere)&deleteuser=1&token=0d30d8b4033a9a523b9574ccf73abad8%2B\
Now, divide this URL into four sections:
A: http: //(Your Wiki domain)/Special:UserMerge?olduser=
B: (OldUserNameHere)
C: &newuser=(NewUserNameHere)&deleteuser=1
D: &token=0d30d8b4033a9a523b9574ccf73abad8%2B\
Now using a text editor or spreadsheet, prefix each spam userIDs with part A and Suffix each with Part C and D. Part C will include the
NewUser(which is a specially created single dummy userID). The Part D,
the Token string is a session-dependent token that will be changed per
user per session. So you will need to get a new token every time a new
session/batch of work is required.
With the above step, you should get a long list of URLs, each good to do a Merge&Delete operation for one user. We can now create a
simple HTML file, view it and use a batch downloader like DownThemAll
in Firefox.
Add two more pieces " Linktext" to each line at
beginning and end. Also add at top and at
bottom and save the file as (for eg:) userlist.html
Open the file in Firefox, use DownThemAll add-on and download all the files! Effectively, you are visiting the Merge&Delete page for
each user and clicking the button!
Although this might look a lengthy and tricky job at first, once you
follow this method, you can remove tens of thousands of users without
much manual efforts.
You can verify if the operation is going well by opening some of the
downloaded html files (or by looking through the recent changes in
another window).
One advantage is that it does not directly edit the
MySQL pages. Nor does it require direct database access.
I did a bit of rewriting to the quoted text, since the original text contains some flaws.

How do you rename a Verity collection in ColdFusion?

Can't seem to rename an existing Verity collection in ColdFusion without deleting, recreating, and rebuilding the collection. Problem is, I have some very large collections I'd rather not have to delete and rebuild from scratch. Any one have a handy trick for this conundrum?
I don't believe that there is an easy way to rename a Verity collection. You can always use
<cfcollection action="map" ...>
to assign an alias to an existing collection, provided you do not need to re-use the original name.
For the Verity part (without considering ColdFusion), it's easy enough to detach a collection, rename it, and reattach it again:
rcadmin> indexdetach
Server Alias:YourDocserver
Index Alias:CollectionName
Index Type [(c)ollection,(t)ree,(p)arametric,(r)ecommendation]:c
Save changes? [y|n]:y
<<Return>> SUCCESS
rcadmin> collpurge
Collection alias:CollectionName
Admin Alias:AdminServer
Save changes? [y|n]:y
<<Return>> SUCCESS
rcadmin> adminsignal
Admin Alias:AdminServer
Type of signal (Shutdown=2,WSRefresh=3,RestartAllServers=4):4
Save changes? [y|n]:y
<<Return>> SUCCESS
Now you can rename the collection directory, and re-attach. (If you are unsure of any of these values, check them with collget before you take it offline).
rcadmin> collset
Admin Alias:AdminServer
Collection Alias:NewCollectionName
Modify Type (Update=0, Insert=1):1
Path:
Gateway[(o)dbc|(n)otes|(e)xchange|(d)ocumentum|(f)ilesys|(w)eb|o(t)her]:
Style Alias:
Document Access (Public=0,Secure=1,Anonymous=2):
Query Parser [(s)imple|(b)oolPlus|(f)reeText|(o)ldFreeText|O(l)dSimple|O(t)her]:
Description:
Max. Search Time(msecs):
Save changes? [y|n]:y
rcadmin> indexattach
Index Alias:NewCollectionName
Index Type [(c)ollection,(t)ree,(p)arametric,(r)ecommendation]:c
Server Alias:YourDocserver
Modify Type (Update=0, Insert=1):1
Index State (offline=0,hidden=1,online=2):2
Threads (default=3):
Save changes? [y|n]:y
<<Return>> SUCCESS
It should now show up again in the 'hierarchyview'.
You can also use the "merge" utility to copy content from one collection to another, with a new name.
Looks like this is not possible. Deleting and re-creating the collection with the desired name appears to be the only approach available.