Integration OpenERP with Asterisk - python

I'm trying to integrate OpenERP and Asterisk with asterisk_click2dial module. Calling from softphone to softphone works, but i cant call from OpenERP to softphone.
manager.conf:
[general]
enabled = yes
webenabled = yes
port = 5038
bindaddr = 0.0.0.0
[openerp]
secret = openerp
deny=0.0.0.0/0.0.0.0
permit=0.0.0.0/0.0.0.0
read = system,call,log,verbose,command,agent,user
write = system,call,log,verbose,command,agent,user
asterisk server config (img)
I'm sure, user settings are ok.
It doesn't works when AMI login is phone number, like in softphone config.
python debugg:
[2012-04-17 14:17:44,072][asterisk] INFO:asterisk_click2dial:Asterisk Click2Dial from 103 to 101
[2012-04-17 14:17:44,078][asterisk] WARNING:web-services:The method action_dial_phone of the object crm.lead can not return `None` !
asterisk server debugg:
== connect attempt from '192.168.1.106' unable to authenticate
While catching SIP packages by Wireshark i saw only reciver number (101#192.168.1.100). I didn't see openerp user number (103), but only Unknown#192.168.1.106. But i first time used Wireshark, so maybe it doesn't matter.
Question is: why OpenERP can't call to softphone, but softphone to softphone can?
Sorry for my english :)

You need to concentrate on the authentication side. If OpenERP (which I am not familiar with) can only send a phone number (or extension number) as a username, then you need to set that as your username in manager.conf. The username portion is what's between the [ and ] above (in this case it's [openerp]. If you do not have the flexibility to set an actual username on the client side of OpenERP, then you'll need to simply replace the [openerp] with [phone_no or ext_no].
Then it should authenticate fine. Wireshark isn't likely to be terribly helpful in this instance.

Related

How to Limit Ratings (or anything else in Django) by IP?

I am using DjangoRatings for a web app which allows anonymous ratings from registered as well as nonregistered users. After I set the IPLimit integer in the DjangoRatings settings.py file, everything works fine; however, when I exceed the number of votes that I have allowed per IP, the entire web page gets reloaded with an “RaiseIPLimit()” error and the entire site goes down which necessitates reloading the previous page via back button. My question is, what can I add to my views.py file to tell django that when DjangoRatings passes the RaiseIPLimit() error, simply print something like “You can only vote once!” message to the user and leave the loaded web page as it is instead of crashing the entire site.
If there’s an easier way to do this general IP checking besides DjangoRatings, I am open to implementing other ways, but DjangoRatings just seems much easier than anything else since the only thing I need IP limits on is rating stuff. To be more clear, here is the exact error that DjangoRatings gives me:
IPLimitReached at /myapp/rating /page1
And this is straight from the DjangoRatings source code:
num_votes = Vote.objects.filter(
content_type=kwargs['content_type'],
object_id=kwargs['object_id'],
key=kwargs['key'],
ip_address=ip_address,
).count()
if num_votes >= getattr(settings, 'RATINGS_VOTES_PER_IP', RATINGS_VOTES_PER_IP):
raise IPLimitReached() ...
kwargs.update(defaults)
if use_cookies:
# record with specified cookie was not found ...
cookie = defaults['cookie'] # ... thus we need to replace old cookie (if presented) with new one
kwargs.pop('cookie__isnull', '') # ... and remove 'cookie__isnull' (if presented) from .create()'s **kwargs
rating, created = Vote.objects.create(**kwargs), True

Python script to hide ploneformgen form after user has filled it out. (For Plone-4.3.2-64.)

After a user has filled out a (ploneformgen) form , I would like to use a custom script adapter to call a python script to change the user’s local role so that they can’t see the form anymore. In other words, I want to prevent the user from filling out (or viewing) the form twice.
I figured that one way to do this is to call the script permission_changer.py which is located in the form folder. The code I have in that script is this:
container.manage_delLocalRoles((‘bob',))
container.reindexObjectSecurity()
Where ‘bob’ is just an example user, who has only the global role FormFiller (which I created under the Security tab of the ZMI) and the local role “Reader” for the form folder.
When I fill out the form (which has a "private" state) as a system admin, the script is called successfully and bob loses his “Reader” local role (which is all he had to begin with), and he can’t see the form anymore. However, when bob fills out the form, a “You do not have sufficient privileges to view this page.” error is displayed, and bob’s local role is not removed. I can’t work out why –– and I’ve tried many different things:
I’ve changed the proxy for the permission_changer.py by clicking on “Proxy” tab for the script in ZMI. I changed it to “Manager”, "System Administrator”, and “Owner”, but that didn’t solve the problem (nor did any combination of those).
I tried changing the proxy by creating a file permission_changer.py.metdadata in the form folder and including this:
[default]
proxy = Manager
but that didn’t work either.
Strangely, when I change bob’s global role to Manager, or System Administrator, or even Viewer, or Editor, the problem goes away and the script runs just fine (I can also change the script so that it adds and removes arbitrary other local roles). (These options are not solutions for me because bob will still be able to see the form because of his global role.)
Also, I tried giving the role FormFiller role every possible permission under the Security tab, but didn’t work.
So, I’m guessing that the problem has to do with the proxy settings, but I can’t work out what I’m doing wrong. I've searched around a lot, and I can't find anyone discussing a similar problem.
Any help would be much appreciated!
Ugly ugly way to handle this may be to access to the data saver field's download method and parse its output to find data to check.
For example, if username is the second pfg field added into form, a custom script adapter that prevents furthers fillings by a user may be
alreadyInDB = False
savedData = ploneformgen.savefield.getSavedFormInputForEdit()
username = request.AUTHENTICATED_USER.getId()
usersInDB = [x.split(',')[1] for x in savedData.split('\r\n') if len(x)>0]
if username in usersInDB:
alreadyInDB = True
if alreadyInDB:
return {'username': 'No way man!'}
I worked out what was going on, but I'm not sure how to describe it precisely. Basically, I found that by calling the script as a Custom Success Action (form > edit > overrides), I don't get the problem. So I think that by calling the script as custom script adapter I was trying to change the user's permission while they were still engaged with the form and that is impossible, even with the Manager proxy role.
I hope that helps. And if anyone has a more precise description of the problem, that would be appreciated.
For granting and revoking the permissions to submit a form, you could:
Create a group (e.g. with the ID "Submitters") and assign the chosen users to it
Make sure the form-folder has the state 'private' and grant View-permissions via the sharing-tab of the form-folder to the group
Add a content-item of type 'Page' in the form-folder's parent (e.g. with the ID 'submitted') and set its state to 'public'
Add a content-item of type 'Custom Script Adapter', select 'Manager' in the field 'Proxy role', and insert the lines below into the field 'Script body':
# Remove current user of group and redirect to [FORM_PARENT_URL]/landing_page_id'.
# If user is not in group, fail silently and continue.
# Fail if landing_page_id does not exist in form-folder, or one of its parents.
#
# Assumes a page with the ID as declared in `landing_page_id` lives in the
# form-folder's parent (or one of its grand-parents, first found wins),
# and holds the state 'public', so users can view it regardless of their
# group-memberships.
#
# Ment to be used after submission of a PloneFormGen-form with private-state and
# a locally assigned Reader-role for the group, so only group-members can view and
# submit the form.
from Products.CMFCore.utils import getToolByName
group_id = 'Submitters' # change as needed
landing_page_id = 'submitted' # change as needed
portal_groups = getToolByName(ploneformgen, 'portal_groups')
user_id = ploneformgen.memberId()
parent_url = '/'.join(ploneformgen.absolute_url().split('/')[:-1])
redirect_to_url = parent_url + '/' + landing_page_id
# Revoke current user's group-membership:
portal_groups.removePrincipalFromGroup(user_id, group_id)
# Let user land in userland:
request.response.redirect(redirect_to_url)
Tested with Plone-4.3.11 and Products.PloneFormGen-1.7.25

Baffling python mysql connection issue

Hello guys I am currently working in a python project at my school. First I want to make clear that I'm not a python programmer (I was just called to put out the flames in this project because no one else would and I was brave enough to say yes).
I have the following problem here. I have to write a method that connects to an existing localhost MySQL database (I'm using connector version 1.0.12 and python 2.6) and then does pretty basic stuff. The parameters are sent by a GTK-written GUI (I didn't write that interface). So I wrote my method like this:
def compMySQL(self, user, database, password, db_level, table_level, column_level):
sql_page_textview = self.mainTree.get_widget('sql_text_view')
sql_page_textview.modify_font(pango.FontDescription("courier 10"))
sql_page_buffer = sql_page_textview.get_buffer()
#Gonna try connecting to DB
try:
print("Calling conn with U:{0} P:{1} DB:{2}".format(user,password,database))
cnxOMC = mysql.connector.connect(user, password,'localhost',database)
except:
print "Error: Database connection failed. User name or Database name may be wrong"
return
#More code ...
But when I run my code I get this:
Calling conn with U:root P:PK17LP12r DB:TESTERS
Error: Database connection failed. User name or Database name may be wrong
And I don't know why, since the arguments sent are the same arguments that get printed (telling me that the GUI the other guy coded works fine) and they are valid login parameters. If I hardcode the login parameters directly insetad of using the GUI everything goes ok and the functions executes properly; the following code executes nice and smooth:
def compMySQL(self, user, database, password, db_level, table_level, column_level):
sql_page_textview = self.mainTree.get_widget('sql_text_view')
sql_page_textview.modify_font(pango.FontDescription("courier 10"))
sql_page_buffer = sql_page_textview.get_buffer()
#Gonna try hardcoding
try:
#print("Calling conn with U:{0} P:{1} DB:{2}".format(user,password,database))
cnxOMC = mysql.connector.connect(user="root", password='PK17LP12r', host='localhost', database='TESTERS')
print 'No prob with conn'
except:
print "Error: Database connection failed. User name or Database name may be wrong"
return
#more code ...
Console output:
No prob with conn
Any ideas guys? This one is killing me. I'm just learning Python but I imagine the problem to be something very easy for a seasoned python developer so any help would be strongly appreciated.
Thanks in advance.
The difference between the two versions is not that you are hard coding the parameters in the second one, it is that you are calling by keyword args rather than positional ones. The docs for MySQL connector don't seem to give the actual positional order, and there's no reason to think they are in the order you've given, so looks like you should always call by kwarg:
cnxOMC = mysql.connector.connect(user=user, password=password,host=host,database=database)

authGSSServerInit looks for wrong entry from keytab

I am attempting to initialize a context for GSSAPI server-side authentication, using python-kerberos (1.0.90-3.el6). My problem is that myserver.localdomain gets converted to myserver - a part of my given principal gets chopped off somewhere. Why does this happen?
Example failure:
>>> import kerberos
>>> kerberos.authGSSServerInit("HTTP#myserver.localdomain")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
kerberos.GSSError: (('Unspecified GSS failure. Minor code may provide more information', 851968), ('Unknown error', 0))
>>>
With the help of KRB5_TRACE I get the reason:
[1257] 1346344556.406343: Retrieving HTTP/myserver#LOCALDOMAIN from WRFILE:/etc/krb5.keytab (vno 0, enctype 0) with result: -1765328203/No key table entry found for HTTP/myserver#LOCALDOMAIN
I can not generate the keytab for plain HTTP/myserver#LOCALDOMAIN because it would force also the users to access the server with such address. I need to get the function to work with the proper FQDN name. As far as I can see authGSSServerInit is supposed to work with the FQDN without mutilating it.
I think the python-kerberos method calls the following krb5-libs (1.9-33.el6) provided functions, the problem might be also in those:
maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &state->server_name);
maj_stat = gss_acquire_cred(&min_stat, state->server_name,GSS_C_INDEFINITE,GSS_C_NO_OID_SET, GSS_C_ACCEPT, &state->server_creds, NULL, NULL);
The kerberos is properly configured on this host, and confirmed to work. I can for instance kinit as user, and perform authentication the tickets. It is just the authGSSServerInit that fails to function properly.
Some of the documentation is misleading:
def authGSSServerInit(service):
"""
Initializes a context for GSSAPI server-side authentication with the given service principal.
authGSSServerClean must be called after this function returns an OK result to dispose of
the context once all GSSAPI operations are complete.
#param service: a string containing the service principal in the form 'type#fqdn'
(e.g. 'imap#mail.apple.com').
#return: a tuple of (result, context) where result is the result code (see above) and
context is an opaque value that will need to be passed to subsequent functions.
"""
In fact the API expects only the type. For instance "HTTP". The rest of the principal gets generated with the help of resolver(3). Although the rest of the kerberos stuff is happy using short names the resolver generates FQDN, but only if dnsdomainname is properly set.
A bit more info for completeness, include following variables in the python command:
This is optional -> KRB5_TRACE=/path-to-log/file.log
Usually this path -> KRB5_CONFIG= /etc/krb5.conf
Usually this path -> KTNAME=/etc/security/keytabs/foo.keytab
For example:
KRB5_TRACE=/path-to-log/file.log KRB5_CONFIG='/etc/krb5.conf' KTNAME=/etc/security/keytabs/foo.keytab /opt/anaconda3.5/bin/python3.6
In python run:
import kerberos
kerberos.authGSSServerInit("user")
Considerations:
In your keytab the principal must be user/host#REALM
Both "user" must be identical
The full principal will be composed by your kerberos client config
If the return code is 0 you are done! Congratz!
If not go to the log file and enjoy debugging :P

wildcard subdomains in a django project

has anyone ever used wildcard subdomains in their application? I need to come up with a way to 'localise' my application. When i say localise i mean anyone who goes to ny.foo.com/items/new/ will be sent to a view which looks through a database and search for new items in ny. Obviously we could replace NY with any state.
Any tips would be great
Thanks!
I would do it using a middleware, eg.:
class StateCodeMiddleware(object):
def process_request(self, request):
bits = request.META['HTTP_HOST'].split('.')
if len(bits) == 3 and len(bits[0]) == 2:
request.state_code = bits[0]
else:
request.state_code = None
# Or a redirect to the default state.
And then in any of your views, you can just check request.state_code and fetch new items only for that state.
Edit: For development, the best method is to setup a local DNS server. Eg. dnsmasq is very easy to configure:
address=/.dev/127.0.0.1 # in dnsmasq.conf
This makes *.dev point to localhost. You'll also have to configure your system to use the local DNS server (on UNIX systems you do this by placing nameserver 127.0.0.1 into /etc/resolve.conf).
Alternatively, you can list all the domain names in your /etc/hosts if it is a finite set:
127.0.0.1 ny.localhost, az.localhost # and so on

Categories