How to access in module - OpenERP web/http.py methods - odoo

In openerp 6.1 windows I tried to capture public IP address when people sign-in and sign-out from the HR module. So, in the hr_attendance module I've added ip_address field. Client Public IP address available in the web\common\http.py environ['REMOTE_ADDR']
from osv import fields, osv
from web.common.http import Root
class hr_attendance(osv.osv):
def _get_ipaddress(self, cr, uid, context=None):
ip = None
try:
# environ['REMOTE_ADDR'] how to get
except Exception, e:
pass
return ip
_inherit = "hr.attendance"
_columns = {
'ip_address' : fields.char('IP Address', readonly=True, size=64)
}
_defaults = {
'ip_address': _get_ipaddress,
}
hr_attendance()
How can I get the client IP address or environ['REMOTE_ADDR"] in the default method? Which class and method do I need to override in hr_attendance module?
In my doubt is which method need to call in http.py and what are the parameter to pass get environ['REMOTE_ADDR'] in the HR Module

That looks like it might be difficult to do without changes to the web layer, because the module code doesn't really know anything about the web server layer. The best I could find after a few minutes of digging was a place where you could copy the IP address from the HTTP request to the OpenERP context dictionary. I think if you added this line to the WebRequest.init() method, it might do what you need.
self.context['remote_addr'] = self.httprequest.remote_addr
I think that context will be passed down to the module code where you can read it.

Related

Odoo allow administrator to see all record in tree view

In tree view I show record where is user_id = uid and for that use:
<field name="domain">[('user_id.id','=',uid)]</field>
I need allow administrator to see all record without domain filter.
Any simple solution?
You can do it using following method.
Remove domain from the action & Inherit search method in python file.
from openerp import models,fields,api,_
from openerp.exceptions import Warning
from openerp.osv import expression
from openerp import SUPERUSER_ID
class mail_message(models.Model):
_inherit = 'mail.message'
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
context=None, count=False, access_rights_uid=None):
""" Override that adds specific access rights of mail.message, to restrict
messages to published messages for public users. """
if uid!=SUPERUSER_ID:
args = expression.AND([[('user_id', '=',uid)], list(args)])
return super(mail_message, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
context=context, count=count, access_rights_uid=access_rights_uid)
When action will execute _search will be called, in which you can check
if user_id is SUPERUSER_ID then do not add domain or add domain.
This may help you.

Python do not serialize object which is not imported in socket

I have written following simple socket application in which object defined in separate file and it works.
# models_object.py
class Person(object):
def __init__(self,name,surname,age):
self.name = name
self.surname = surname
self.age = age
def __str__(self):
return self.name + " " + self.surname
#client.py
import cPickle,socket
from model_objects import Person
def client():
client = socket.socket()
host = socket.gethostname()
port = 8000
adem_kerenci = Person("Adem","Kerenci",22)
serialized_object = cPickle.dumps(adem_kerenci)
client.connect((host, port))
client.send(serialized_object)
client.close()
client()
#service.py
import cPickle,socket
def server():
server = socket.socket()
host = socket.gethostname()
port = 8000
server.bind((host, port))
server.listen(1)
connection, address = server.accept()
recieved_data = connection.recv(2**20)
print cPickle.loads(recieved_data)
connection.close()
server()
However, if I write Person class definition into client.py, code raises following error.
Traceback (most recent call last):
File "service.py", line 14, in <module>
server()
File "service.py", line 11, in server
print cPickle.loads(recieved_data)
AttributeError: 'module' object has no attribute 'Person'
Is there any relation between importing and serializing?
Note: We tried python 2.7
From documentation:
Note that functions (built-in and user-defined) are pickled by “fully qualified” name reference, not by value. This means that only the function name is pickled, along with the name of the module the function is defined in. Neither the function’s code, nor any of its function attributes are pickled. Thus the defining module must be importable in the unpickling environment, and the module must contain the named object, otherwise an exception will be raised.
This means that the object you are unpickling in the server should be importable too from the server code with the same "fully qualified" name which in the first example is: model_objects.Person. This is apparent in the first case if you try splitting the client.py and model_objects.py in one folder and service.py in another folder which will give you the same error as it is trying to import model_objects.py inside service.py but it couldn't find it.
So in the second case you can copy the class Person as well to the server code and it will work but this is bad practice or make a shared folder for both client and server which is shared production code as well (better practice).
This is because during unpickling python needs the class of the object to reinstantiate the object and use it.

ServiceStack: Can we Pass Data through a RequestFilterAttribute to the calling service

Maybe I'm thinking about this wrong, but I'm trying to create a custom attribute for our CMS to handle auth checks.
https://gist.github.com/sitefinitysteve/62ab761256a64a84d8a6#file-sitefinityjwt-cs-L39
So if this service is called from within the CMS from a logged in user, user data is all there for the service method already.
But in the context of being called from an app, the user is technically Anonymous, however I can decode the token and get the user just fine... but not sure how to like pass that over to the service.
Am I just maybe looking at this wrong, and the proper thing to do is to call a CMS API method to just log that person in (seems slow if I already have the persons user object from line 33, and the service context expires instantly.
Use Request.Items Dictionary
You would use the IRequest.Items dictionary for any data you want to pass throughout ServiceStack's Request Pipeline:
//RequestFilter:
req.Items["info"] = new MyRequestInfo { ... };
In Service:
var info = (MyRequestInfo)base.Request.Items["info"];
Have DTO's share common interface
Another option for adding extra info to your Service is to have Request DTO's implement an interfaces, e.g:
public interface IHasInfo
{
MyRequestInfo Info { get; set; }
}
Which you could then populate in your Request Filter, e.g:
((MyRequestInfo)dto).Info = new MyRequestInfo { ... };
Access in Service like any other DTO property, e.g:
public object Any(Request request)
{
var info = request.Info;
}

Netflix Ribbon and Polling for Server List

I'm currently trying out the Netflix Ribbon library and I'm trying to dynamically update a list of available endpoints to load balance.
I've successfully created a httpResourceGroup that uses a configuration based server list, e.g.:
httpResourceGroup = Ribbon.createHttpResourceGroup("searchServiceClient",
ClientOptions.create()
.withMaxAutoRetriesNextServer(3)
.withLoadBalancerEnabled(true)
.withConfigurationBasedServerList(serverList))
However, I'd like to be able to use a DynamicServerList in the httpResourceGroup. I've managed to build a load balancer as follows:
LoadBalancerBuilder.<Server>newBuilder()
.withDynamicServerList(servicesList)
.buildDynamicServerListLoadBalancer();
but I can't find a way to swap out the load balancer configured by the httpResourceGroup ClientOptions.
Anyone know how I can do this?
The solution is to not specify withConfigurationBasedServerList() when constructing an HttpResourceGroup since this I believe this is meant for a fixed list though I am not sure. There are many ways to initialize a dynamic load balancer (typically you would never swap it out, but reuse the same load balancer and swap out new Servers as they become available or go away. The most straightforward way to do this might be via Archaius-based configuration.
Option 1
Create a config.properties file on the classpath containing the following
ribbon.NIWSServerListClassName=com.example.MyServerList
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
Option 2
System.setProperty("ribbon.NIWSServerListClassName", "com.example.MyServerList");
System.setProperty("ribbon.NFLoadBalancerRuleClassName", "com.netflix.loadbalancer.RoundRobinRule");
Create a ServerList implementation
import java.util.Arrays;
import java.util.List;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
public class MyServerList implements ServerList<Server> {
#Override
public final List<Server> getUpdatedListOfServers() {
// TODO do some fancy stuff here
return Arrays.asList(new Server("1.2.3.4", 8888), new Server("5.6.7.8", 9999));
}
#Override
public final List<Server> getInitialListOfServers() {
return Arrays.asList(new Server("1.2.3.4", 8888), new Server("5.6.7.8", 9999));
}
}
Run the code
HttpResourceGroup httpResourceGroup = Ribbon.createHttpResourceGroup("searchServiceClient",
ClientOptions.create()
.withMaxAutoRetriesNextServer(3);
HttpRequestTemplate<ByteBuf> recommendationsByUserIdTemplate = httpResourceGroup.newTemplateBuilder("recommendationsByUserId", ByteBuf.class)
.withMethod("GET")
.withUriTemplate("/users/{userId}/recommendations")
.withFallbackProvider(new RecommendationServiceFallbackHandler())
.withResponseValidator(new RecommendationServiceResponseValidator())
.build();
Observable<ByteBuf> result = recommendationsByUserIdTemplate.requestBuilder()
.withRequestProperty("userId", “user1")
.build()
.observe();
It sounds like you already have a ServerList implementation which is where you would do any event driven updates to your server list, but keep the load balancer the same.

Django Rest Framework custom permissions per view

I want to create permissions in Django Rest Framework, based on view + method + user permissions.
Is there a way to achieve this without manually writing each permission, and checking the permissions of the group that the user is in?
Also, another problem I am facing is that permission objects are tied up to a certain model. Since I have views that affect different models, or I want to grant different permissions on the method PUT, depending on what view I accessed (because it affects different fields), I want my permissions to be tied to a certain view, and not to a certain model.
Does anyone know how this can be done?
I am looking for a solution in the sort of:
Create a Permissions object with the following parameters: View_affected, list_of_allowed_methods(GET,POST,etc.)
Create a Group object that has that permission associated
Add a user to the group
Have my default permission class take care of everything.
From what I have now, the step that is giving me problems is step 1. Because I see no way of tying a Permission with a View, and because Permissions ask for a model, and I do not want a model.
Well, the first step could be done easy with DRF. See http://www.django-rest-framework.org/api-guide/permissions#custom-permissions.
You must do something like that:
from functools import partial
from rest_framework import permissions
class MyPermission(permissions.BasePermission):
def __init__(self, allowed_methods):
super().__init__()
self.allowed_methods = allowed_methods
def has_permission(self, request, view):
return request.method in self.allowed_methods
class ExampleView(APIView):
permission_classes = (partial(MyPermission, ['GET', 'HEAD']),)
Custom permission can be created in this way, more info in official documentation( https://www.django-rest-framework.org/api-guide/permissions/):
from rest_framework.permissions import BasePermission
# Custom permission for users with "is_active" = True.
class IsActive(BasePermission):
"""
Allows access only to "is_active" users.
"""
def has_permission(self, request, view):
return request.user and request.user.is_active
# Usage
from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import IsActive # Path to our custom permission
class ExampleView(APIView):
permission_classes = (IsActive,)
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
I took this idea and got it to work like so:
class genericPermissionCheck(permissions.BasePermission):
def __init__(self, action, entity):
self.action = action
self.entity = entity
def has_permission(self, request, view):
print self.action
print self.entity
if request.user and request.user.role.access_rights.filter(action=self.action,entity=self.entity):
print 'permission granted'
return True
else:
return False
I used partially in the decorator for the categories action in my viewset class like so:
#list_route(methods=['get'],permission_classes=[partial(genericPermissionCheck,'Fetch','Categories')])
def Categories(self, request):
"access_rights" maps to an array of objects with a pair of actions and object e.g. 'Edit' and 'Blog'