I would like to know which is best way to manage the protocols active in Twisted or if there is no concrete way.
In my current app I created a dictionary where there are two fields. At one I put the remote user and the local user to another. Both fields are lists so I can add several items.
The method I'm using is the following. First I check by a try-except if the dictionary exists. If there is no dictionary, I create it.
try:
if self.factory.active_protocols:
log.msg('Active protocols dictionary already created')
except Exception as e:
log.err(e)
self.factory.active_protocols = {}
self.factory.active_protocols.setdefault('localUsr', [])
self.factory.active_protocols.setdefault('remoteUsr', [])
Then I check if the local user is in the local users list. If there is no user I adds it to the list of local users. If the list exists, it throws an error.
if sUsername in self.factory.active_protocols['localUsr']:
log.err('Client already logged in')
raise UnauthorizedLogin('Client already logged in')
else:
# Attach local user to active protocols list.
self.sUsername = sUsername
self.factory.active_protocols['localUsr'].append(self.sUsername)
If the conditions are right the remote user is also added to the list of remote users using the following code.
# If time is correct, attach remote user to active_protocols
self.factory.active_protocols['remoteUsr'].append(remoteUsr)
When I disconnect users, I delete the lists using the following code.
if self.sUsername in self.factory.active_protocols['localUsr']:
self.factory.active_protocols['localUsr'] = []
if self.remoteUsr in self.factory.active_protocols['remoteUsr']:
self.factory.active_protocols['remoteUsr'] = []
Is there a more correct way to do it? Should implement some special kind of dictionary? To Create a list? Does using a proprietary method of Twisted?
I have been looking for information about internet and I have not found anything conclusive about it.
Thank you!
No, there is no special type of list or dictionary in Twisted you can use for this.
Twisted's job is turning network events into method calls on your objects. Once you you are implementing those methods on those objects, as much as possible, you want to use regular Python data structures. There are certain things in Twisted, like Deferreds, which are data structures you can use to implement certain asynchronous data-flow patterns, but for something as simple as a basic observer pattern with multiple entities in a list, regular lists and dictionaries and such are just fine.
Related
So, I'm making a text based game and I want that whenever a user types a command my bit DMS the user and starts the story for that user. I'm not sure how to do this for multiple users. Like if a game has already been initiated and someone else wants to start a new one they should be able to irrespective to the progress of the user that is already playing
Well since you haven't provided any code it will have to be a description based answer.
For storing data in cache use a dictionary
data = {}
...
data[member.id] = {level: 0, money: 0}
This would storage the variables level and money inside the data variable you can access it with data[member.id].
If you are wanting to store data over long term have a look at databases such as MongoDB or MySQL/MariaDB.
Your code must be async otherwise there will be blocking while things are being calculated. For example, if you are fetching data using requests use aiohttp or another asynchronous library for it.
I have a Django application to log the character sequences from an autocomplete interface. Each time a call is made to the server, the parameters are added to a list and when the user submits the query, the list is written to a file.
Since I am not sure how to preserve the list between subsequent calls, I relied on a global variable say query_logger. Now I can preserve the list in the following way:
def log_query(query, completions, submitted=False):
global query_logger
if query_logger is None:
query_logger = list()
query_logger.append(query, completions, submitted)
if submitted:
query_logger = None
While this hack works for a single client sending requests I don't think this is a stable solution when requests come from multiple clients. My question is two-fold:
What is the order of execution of requests: Do they follow first come first serve (especially if the requests are asynchronous)?
What is a better approach for doing this?
If your django server is single-threaded, then yes, it will respond to requests as it receives them. If you're using wsgi or another proxy, that becomes more complicated. Regardless, I think you'll want to use a db to store the information.
I encountered a similar problem and ended up using sqlite to store the data temporarily, because that's super simple and easy to manage. You'll want to use IP addresses or create a unique ID passed as a url parameter in order to identify clients on subsequent requests.
I also scheduled a daily task (using cron on ubuntu) that goes through and removes any incomplete requests that haven't been completed (excluding those started in the last hour).
You must not use global variables for this.
The proper answer is to use the session - that is exactly what it is for.
Simplest (bad) solution would be to have a global variable. Which means you need some in memory location or a db to store this info
I have a fairly simple use case but can't figure out how to stitch it together.
Basically I want to use user-restricted access for regular users, i.e. they can upload files via an API and other users cannot touch those files via the API.
At the same time I want a special user (admin/super-user) to be able to use the API to GET e.g. all files for a specific user.
Does anybody have any pointers to examples of this or can help point me in the right direction to do this?
One idea I thought of was to pass an additional (optional) parameter to check_auth containing the _id of the user that the admin wants to look at, so if the admin passes in that parameter it will override the admins own _id. Would this work or does check_auth have a set parameter list? any security issues with this approach?
Or is there a better approach - a separate API instance perhaps that uses the same mongoDB collections (is that even possible?).
Regards,
Anton
I want to add the 'check username available' functionality on my signup page using AJAX. I have few doubts about the way I should implement it.
With which event should I register my AJAX requests? We can send the
requests when user focus out of the 'username' input field (blur
event) or as he types (keyup event). Which provides better user
experience?
On the server side, a simple way of dealing with requests would be
to query my main 'Accounts' database. But this could lead to a lot
of request hitting my database(even more if we POST using the keyup
event). Should I maintain a separate model for registered usernames
only and use that to get better results?
Is it possible to use Memcache in this case? Initializing cache with
every username as key and updating it as we register users and use a
random key to check if cache is actually initialized or pass the
queries directly to db.
Answers -
Do the check on blur. If you do it on key up, you will be hammering your server with unnecessary queries, annoying the user who is not yet done typing, and likely lag the typing anyway.
If your Account entity is very large, you may want to create a separate AccountName entity, and create a matching such entity whenever you create a real Account (but this is probably an unnecessary optimization). When you create the Account (or AccountName), be sure to assign id=name when you create it. Then you can do an AccountName.get_by_id(name) to quickly see if the AccountName has already been assigned, and it will automatically pull it from memcache if it has been recently dealt with.
By default, GAE NDB will automatically populate memcache for you when you put or get entities. If you follow my advice in step 2, things will be very fast and you won't have to mess around with pre-populating memcache.
If you are concerned about 2 people simultaneously requesting the same user name, put your create method in a transaction:
#classmethod
#ndb.transactional()
def create_account(cls, name, other_params):
acct = Account.get_by_id(name)
if not acct:
acct = Account(id=name, other param assigns)
acct.put()
I would recommend the blur event of the username field, combined with some sort of inline error/warning display.
I would also suggest maintaining a memcache of registered usernames, to reduce DB hits and improve user experience - although probably not populate this with a warm-up, but instead only when requests are made. This is sometimes called a "Repository" pattern.
BUT, you can only populate the cache with USED usernames - you should not store the "available" usernames here (or if you do, use a much lower timeout).
You should always check directly against the DB/Datastore when actually performing the registration. And ideally in some sort of transactional method so that you don't have race conditions with multiple people registering.
BUT, all of this work is dependant on several things, including how busy your app is and what data storage tech you are using!
I am trying to modify a python based-authenticator for murmur (voip software) to work with my ldap tree.
The LDAP authenticator is available at:
http://www.winex.org/linux/zealot/src/mumble-scripts/Authenticators/LDAP/LDAPauth.py
It works, but not quite with my ldap layout, so I have to modify it a bit. I know an approach that could work, but unfortunately I have no more knowledge about python than what I learned from google (I have some other programming expertise though).
My ldap layout looks like this:
charName=xxx, ou=people, dc=xxx, dc=com
Under this there are attributes stored such as userPassword and login among others.
The python script above is tailored to use a ldap bind to authenticate. In this case I would have to bind as "charName=logindatafromapp, ou=people, dc=xxx, dc=com". Unfortunately people don't log in with "charName" but with "login" which is an attribute, but isn't identical with "charName".
I do not know a way to bind to an attribute, so here is my idea:
I first bind as ldap admin and perform a search over all entries for "logindatafromapp" and match that value against "login". If a match is found I grab the matching "charName" and re-bind with that charName as originally intended.
I am currently stuck on querying the "charName" value and at assigning that value to a variable, so i could use it in a second ldap bind (google didn't really help me).
Here is my code:
ldap_conn = ldap.initialize(ldap_uri, 0)
ldap_conn.bind_s("cn=admin,dc=xxxxxxxx,dc=com","pass")
res = ldap_conn.search_s('ou=people,dc=xxxxxx,dc=com', ldap.SCOPE_ONELEVEL,'login=trony',['charName'])
print(res)
It then prints "[('charName=Trony,ou=people,dc=xxxxxxx,dc=com', {'charName': ['Trony']})]".
(the "login=trony") is a temporary filter that I would have to replace with the applogin var. My problem is now how can I assign "Trony" (in this case) to a variable? The output seems to be a special struct?
'Trony' is in
res[0][1]['charName'][0]
You take the first element of the list — it's a tuple; then the first element of the tuple; it's a dictionary; then value of the dictionary for the key 'charName'; it's a list once again; and then the first element of the list.
There are at least two alternatives:
Use the method you describe to search for the entry using the information you have, in this case the value of the login attribute as entered by the user and then using the DN that was found in a simple or SASL bind or
Use SASL with identity mapping to map the authId (the value of the login attribute) in such a way that a SASL bind will succeed where only the value of the login attribute is known
The first method requires a search and then a bind, the second might require that user entries have reversible passwords (AES is a good encryption scheme for that purpose) depending on the SASL mechanism that is chosen. Using SASL with the DIGEST-MD5 mechanism would provide a way to map identities as described (all professional-quality LDAP servers support such a mapping mechanism) and would obviate the need to send a password in the clear over a network, but has the disadvantage of not being as secure as using simple bind where the password is stored as a salted SHA-2 digest. Although DIGEST-MD5 should not be used because it requires reversible passwords and thus is not as secure as using the strong SHA-2 (with salt) it is available for applications that require it.