Esempio n. 1
0
 def decode_auth_token(auth_token):
     """
     Validates the auth token
     :param auth_token:
     :return: integer|string
     """
     try:
         payload = jwt.decode(auth_token,
                              current_app.config.get('SECRET_KEY'))
         is_blacklisted_token = BlacklistToken.check_blacklist(auth_token)
         if is_blacklisted_token:
             raise AuthError(
                 {
                     "code": "blacklisted_token",
                     "description": "blacklisted token, "
                     "please sign in again"
                 }, 401)
         else:
             return User.query.filter_by(id=payload['sub']).first()
     except jwt.ExpiredSignatureError:
         raise AuthError(
             {
                 "code": "token_expired",
                 "description": "token has expired"
             }, 401)
     except Exception:
         raise AuthError(
             {
                 "code": "invalid_token",
                 "description": "Unable to parse authentication token."
             }, 401)
Esempio n. 2
0
    def getRole(self, desired=None):
        """ Checks if the user is authorised.
        Checks the roles. 
        If the desired role name is given and it is listed in the user's roles list, the desired role is returned.
        The first role is returned otherwise. 
        Returns json {roleName: "police", roleTitle: "Policie Ceske republiky"}
        """
        strDes = str(desired)
        logging.debug("[LaymanAuthLiferay][getRole]: '%s'"%strDes)
        if not self.authorised:
            logging.error("[LaymanAuthLiferay][getRole] The user is not authorised")
            raise AuthError(401, "I am sorry, but you are not authorised")
        if self.authJson["userInfo"] and self.authJson["userInfo"]["roles"]:
            roles = self.authJson["userInfo"]["roles"]
            if len(roles) < 1:
                logging.error("[LaymanAuthLiferay][getRole] Cannot determine the workspace - Liferay provided empty list of roles")
                raise AuthError(500,"Cannot determine the workspace - Liferay provided empty list of roles")            

            theRole = roles[0]
            for r in roles:
                if desired == r["roleName"]:
                    theRole = r

            #lower and spaces
            #theRole["roleName"] = theRole["roleName"].lower()
            #theRole["roleName"] = "_".join(theRole["roleName"].split(' '))
            roleName = theRole["roleName"]
            logging.debug("[LaymanAuthLiferay][getRole] The role: '%s'"% roleName)
            return theRole
        else: 
            logging.error("[LaymanAuthLiferay][getRole] Cannot determine the workspace - Liferay did not provide user's roles")
            raise AuthError(500,"Cannot determine the workspace - Liferay did not provide user's roles")
Esempio n. 3
0
    def getUserName(self):
        if not self.authorised:
            raise AuthError(401,"I am sorry, but you are not authorised")

        if self.authJson["userInfo"] and self.authJson["userInfo"]["screenName"]:
            screenName = self.authJson["userInfo"]["screenName"]
            return screenName
        else: 
            raise AuthError(500, "Cannot determine the user name - Liferay did not provide user's screenName")
Esempio n. 4
0
    def getFSUserDir(self):
        """Get user working directory. Dirname == screenName from Liferay
        """
        if not self.authorised:
            raise AuthError(401,"I am sorry, but you are not authorised")

        if self.authJson["userInfo"] and self.authJson["userInfo"]["screenName"]:
            fsDir = self.config.get("FileMan","homedir") + self.authJson["userInfo"]["screenName"]
            return fsDir
        else: 
            raise AuthError(500, "Cannot determine the working directory - Liferay did not provide user's screenName")
Esempio n. 5
0
    def getAllRoles(self):
        """ Returns list of all roles as JSON. We assume this is not secret. """

        # Learn URL of AllRoles service
        url = self.config.get(
            "Authorization", "allroles"
        )  # http://erra.ccss.cz/g4i-portlet/service/list/roles/en
        logging.debug("[LaymanAuthLiferay][getAllRoles] AllRoles url: %s" %
                      url)

        # Request all roles from LifeRay
        import httplib2
        h = httplib2.Http()
        header, content = h.request(url, "GET")
        logging.debug("[LaymanAuthLiferay][getAllRoles] response header: %s" %
                      header)
        logging.debug("[LaymanAuthLiferay][getAllRoles] response content: %s" %
                      content)

        # Parse the response
        try:
            allRolesJson = json.loads(content)
            logging.debug(
                "[LaymanAuthLiferay][getAllRoles] AllRoles reply succesfully parsed"
            )
        except ValueError, e:
            logging.error(
                "[LaymanAuthLiferay][getAllRoles] Cannot parse AllRoles reply: '%s'"
                % content)
            raise AuthError(
                500, "Cannot parse GET All Roles response [%s] as JSON:%s" %
                (content, e))
Esempio n. 6
0
    def _parseUserInfo(self, content):

        # Process the response
        try:
            self.authJson = json.loads(content)

            # Role names: lower() and spaces
            if self.authJson["userInfo"] and self.authJson["userInfo"]["roles"]:
                roles = self.authJson["userInfo"]["roles"]
                for rr in roles:
                    rr["roleName"] = rr["roleName"].lower()
                    rr["roleName"] = "_".join(rr["roleName"].split(' '))
                rolesStr = json.dumps(roles)
                logging.debug(
                    "[LaymanAuthLiferay][_parseUserInfo] Roles: '%s'" %
                    rolesStr)

            logging.debug(
                "[LaymanAuthLiferay][_parseUserInfo] Liferay reply succesfully parsed"
            )
        except ValueError, e:
            logging.error(
                "[LaymanAuthLiferay][_parseUserInfo] Cannot parse Liferay reply: '%s'"
                % content)
            raise AuthError(
                500,
                "Cannot parse Liferay response [%s] as JSON:%s" % (content, e))
Esempio n. 7
0
    def update(self, user, transaction_id, **kwargs):
        """ Update single transaction for all given keyword arguments """
        tx = self.get_transaction(transaction_id)
        if tx.user_id == user.id:
            CashTransaction.query.filter_by(id=transaction_id).update(kwargs)
            db.session.commit()
            return CashTransaction.query.filter_by(id=transaction_id).first()

        raise AuthError({"code": "unauthorised", "message": "unable to find transaction"}, 401)
Esempio n. 8
0
class LaymanAuth:

    config = None
    auth = None

    authorised = False

    def __init__(self, config=None):
        self._setConfig(config)

    # Service Authorisation Methods #

    def canread(self):
        """Can particular user read from the service?

            :returns: boolean
        """
        return False

    def canwrite(self):
        """Can particular user write to the service?

            :returns: boolean
        """
        return False

    # User/Group configuration methods #

    def getFSDir(self):
        """Returns full abs path to target file manager directory according to
        configuration value and user

        NOTE: this method is to be overwritten according to specified
        Authorization method. This default method returns path to working
        directory, regardless, which user is logged in.

        :returns: path absolute path to target dir
        """

        # target dir configuration value
        dirname = os.path.abspath(self.config.get("FileMan", "targetdir"))

        # exists or not - create
        if not os.path.isdir(dirname):
            try:
                os.mkdir(dirname)
            except OSError, e:
                raise AuthError(500,"Could not create target directory [%s]:%s"%\
                        (dirname, e))

        # check directory permission
        if not os.access(dirname, 7):
            raise AuthError(
                500,
                "Write access denied for target directory [%s]" % (dirname))

        return dirname
Esempio n. 9
0
 def getRoles(self):
     """ Returns list of roles: 
         [
            {
                roleTitle: "User",
                roleName: "User"
            },
            {
                roleTitle: "pozarnaja",
                roleName: "hasici"
            } 
        ]
     """
     logging.debug("[LaymanAuthLiferay][getRoles]")
     if not self.authorised:
         logging.error(
             "[LaymanAuthLiferay][getRoles] The user is not authorised")
         raise AuthError(401, "I am sorry, but you are not authorised")
     if self.authJson["userInfo"] and self.authJson["userInfo"]["roles"]:
         roles = self.authJson["userInfo"]["roles"]
         if len(roles) < 1:
             logging.error(
                 "[LaymanAuthLiferay][getRoles] Cannot determine the workspace - Liferay provided empty list of roles"
             )
             raise AuthError(
                 500,
                 "Cannot determine the workspace - Liferay provided empty list of roles"
             )
         #lower() and spaces
         #for rr in roles:
         #    rr["roleName"] = rr["roleName"].lower()
         #    rr["roleName"] = "_".join(rr["roleName"].split(' '))
         rolesStr = json.dumps(roles)
         logging.debug("[LaymanAuthLiferay][getRoles] The roles: '%s'" %
                       rolesStr)
         return roles
     else:
         logging.error(
             "[LaymanAuthLiferay][getRoles] Cannot determine the workspace - Liferay did not provide user's roles"
         )
         raise AuthError(
             500,
             "Cannot determine the workspace - Liferay did not provide user's roles"
         )
Esempio n. 10
0
 def authorise(self, JSESSIONID):
     """ Authorise the given JSESSIONID against the Slavek's service:
     call the service and process the response """
     logging.debug("[LaymanAuthLiferay][authorise] %s"% JSESSIONID)
     if JSESSIONID is None or JSESSIONID == "":
         raise AuthError(401, "Authentication failed: No JSESSIONID given")
     self.JSESSIONID = JSESSIONID
     content = self._getUserInfo(JSESSIONID)
     self._parseUserInfo(content)
     return self.authorised
Esempio n. 11
0
    def decorated(*args, **kwargs):
        token = get_token_auth_header()
        if token:
            user = User.decode_auth_token(token)

            return f(user, *args, **kwargs)
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Unable to find appropriate key"
            }, 401)
Esempio n. 12
0
    def login(email, password):
        """ Login a user by email and password validation, return token on success """
        user = User.query.filter_by(email=email).first()

        if user:
            if bcrypt.checkpw(password.encode('utf-8'),
                              user.password_hash.encode('utf-8')):
                return user.encode_auth_token()
        raise AuthError(
            {
                "code": "invalid_credentials",
                "message": "invalid credentials"
            }, 401)
Esempio n. 13
0
def get_token_auth_header():
    """Obtains the Access Token from the Authorization Header
    """
    auth = request.headers.get("Authorization", None)
    if not auth:
        raise AuthError(
            {
                "code": "authorization_header_missing",
                "description": "Authorization header is expected"
            }, 401)

    parts = auth.split()

    if parts[0].lower() != "bearer":
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Authorization header must start with"
                " Bearer"
            }, 401)
    elif len(parts) == 1:
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Token not found"
            }, 401)
    elif len(parts) > 2:
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Authorization header must be"
                " Bearer token"
            }, 401)

    token = parts[1]
    return token
Esempio n. 14
0
 def logout(auth_token):
     """ Blacklist auth_token and return None on success """
     user = User.decode_auth_token(auth_token)
     if user:
         # mark the token as blacklisted
         blacklist_token = BlacklistToken(token=auth_token)
         try:
             # insert the token
             blacklist_token.save()
             return None
         except Exception as e:
             logging.error(e)
             raise
     else:
         raise AuthError(
             {
                 "code": "invalid_user",
                 "message": "unable to find user"
             }, 401)
Esempio n. 15
0
    def getFSDir(self):
        """Returns full abs path to target file manager directory according to
        configuration value and user

        NOTE: this method is to be overwritten according to specified
        Authorization method. This default method returns path to working
        directory, regardless, which user is logged in.

        :returns: path absolute path to target dir
        """

        # target dir configuration value
        dirname = os.path.abspath(self.config.get("FileMan", "targetdir"))

        # exists or not - create
        if not os.path.isdir(dirname):
            try:
                os.mkdir(dirname)
            except OSError, e:
                raise AuthError(500,"Could not create target directory [%s]:%s"%\
                        (dirname, e))
Esempio n. 16
0
    def GET(self, name=None):

        try:
                logging.info("[LayMan][GET] %s" % name)
                params = repr(web.input())
                logging.info("[LayMan][GET] Parameters: %s ... %s" %
                    (str(params)[:500], str(params)[-500:]))

                if not self.auth.authorised:
                    logging.error("[LayMan][GET] Unauthorised")
                    raise AuthError(401, "Authorisation failed. Are you logged-in?")

                code = None    # 200, 404...
                retval = None  # success: returned value. failure: error message.
                origName = name
                path = [d for d in name.split(os.path.sep) if d]

                # GET "http://localhost:8080/layman/fileman/"
                if path[0] == "fileman":

                    from fileman import FileMan
                    fm = FileMan()

                    # /fileman
                    if len(path) == 1:
                        logging.info("[LayMan][GET /fileman]")
                        (code, retval) = fm.getFiles(self.auth.getFSUserDir())

                    # /fileman/<file>
                    elif len(path) == 2:
                        (code, retval) = fm.getFile(self._getTargetFile(path[1]))

                    # /fileman/detail/<file>
                    elif len(path) == 3 and\
                        path[1] == "detail":
                        (code, retval) = fm.getFileDetails(self._getTargetFile(path[2]))

                    else:
                        (code, retval) = self._callNotSupported(restMethod="GET", call=origName)

                elif path[0] == 'publish':
                    
                    from layed import LayEd
                    le = LayEd()

                    roles = self.auth.getRoles()
                    (code,retval) = le.getLayers(roles)

                # Get the list of tables in db (or other data)
                elif path[0] == 'data':
                
                    # /data    
                    if len(path) == 1:
                        from layed import LayEd
                        le = LayEd()

                        roles = self.auth.getRoles()
                        (code,retval) = le.getData(roles)

                    elif len(path) == 2:

                        # /layed/groups
                        if path[1] == "groups":
                            (code, retval) = self.auth.getRolesStr()

                        # /layed/allgroups
                        elif path[1] == "allgroups":
                            (code, retval) = self.auth.getAllRolesStr()

                        else:
                            (code, retval) = self._callNotSupported(restMethod="GET", call=origName)

                    else:
                        (code, retval) = self._callNotSupported(restMethod="GET", call=origName)


                elif path[0] == 'layed':

                    from layed import LayEd
                    le = LayEd()

                    # /layed[?usergroup=FireBrigade]
                    if len(path) == 1:
                        """ Get the json of the layers.
                        If usergroup parameter is specified, only the layers
                        of the corresponding workspace are returned.
                        Otherwise, the layers of all groups allowed are returned
                        in proprietary json, ordered by group (i.e. workspace)
                        """
                        logging.info("[LayMan][GET /layed]")
                        inpt = web.input(usergroup=None)
                        if inpt.usergroup == None: # workspace not given, go for all
                            roles = self.auth.getRoles()
                        else: # workspace given, go for one
                            role = self.auth.getRole(inpt.usergroup)
                            roles = [role]
                        (code,retval) = le.getLayers(roles)

                    elif len(path) == 2:

                        # /layed/workspaces
                        if path[1] == "workspaces":
                            (code, retval) = le.getWorkspaces()

                        # /layed/groups
                        elif path[1] == "groups":
                            (code, retval) = self.auth.getRolesStr()

                        # /layed/allgroups
                        elif path[1] == "allgroups":
                            (code, retval) = self.auth.getAllRolesStr()

                        else:
                            (code, retval) = self._callNotSupported(restMethod="GET", call=origName)

                    elif len(path) == 3:

                        # /layed/config/<layer>?usergroup=FireBrigade
                        if path[1] == "config":
                            layerName = path[2]
                            inpt = web.input(usergroup=None)
                            gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup)
                            (code, retval) = le.getLayerConfig(gsWorkspace, layerName)

                        # /layed/workspaces/<ws>
                        elif path[1] == "workspaces":
                            (code, retval) = le.getWorkspace(path[2])

                        else:
                            (code, retval) = self._callNotSupported(restMethod="GET", call=origName)

                    else:
                        (code, retval) = self._callNotSupported(restMethod="GET", call=origName)

                elif path[0] == "geoserver":
                    ws = None
                    g = None

                    from layed.gsconfig import GsConfig
                    code = 200

                    if path[1] == "style" and len(path) >= 3:
                        #if len(path) > 3:
                        #    ws = path[-2]
                        g = GsConfig()
                        retval = g.getStyle(path[-1])
                        web.header("Content-type", "text/xml")

                else:
                    (code, retval) = self._callNotSupported(restMethod="GET", call=origName)

                success = self._setReturnCode(code)
                if not success:
                    retval  = self._jsonReply(code, message=retval, success=success)
                # else: we return the returned value directly
                return retval

        except LaymanError as le:
            return self._handleLaymanError(le)

        except Exception as e:
            return self._handleException(e)
Esempio n. 17
0
class LaymanAuthLiferay(LaymanAuth):

    # JSESSIONID from Liferay, provided by the Client
    JSESSIONID = None

    # Has been successfully authorised
    authorised = False

    # Json reply from Slavek's service to http://erra.ccss.cz/g4i-portlet/service/sso/validate/JSESSIONID request
    # Example:
    # {
    #    resultCode: "0",
    #    userInfo: {
    #       lastName: "Doe",
    #       email: "*****@*****.**",
    #       roles: [
    #           {
    #               roleTitle: "User",
    #               roleName: "User"
    #           },
    #           {
    #               roleTitle: "pozarnaja",
    #               roleName: "hasici"
    #           }, 
    #       ],
    #       userId: 10432,
    #       screenName: "test",
    #       language: "en",
    #       firstName: "John",
    #       groups: [ ]
    #   },
    #   leaseInterval: 1800
    # }
    authJson = None

    def __init__(self,config=None,JSESSIONID=None):
        LaymanAuth.__init__(self,config)

    # Authorise 
    def authorise(self, JSESSIONID):
        """ Authorise the given JSESSIONID against the Slavek's service:
        call the service and process the response """
        logging.debug("[LaymanAuthLiferay][authorise] %s"% JSESSIONID)
        if JSESSIONID is None or JSESSIONID == "":
            raise AuthError(401, "Authentication failed: No JSESSIONID given")
        self.JSESSIONID = JSESSIONID
        content = self._getUserInfo(JSESSIONID)
        self._parseUserInfo(content)
        return self.authorised
    
    # Get the user info from Slavek's service
    def _getUserInfo(self,JSESSIONID):

        # Learn URL of Slavek's service
        url = self.config.get("Authorization","url") + JSESSIONID
        logging.debug("[LaymanAuthLiferay][_getUserInfo] Authorisation url: %s"% url)
    
        # Request the authentication
        import httplib2
        h = httplib2.Http()
        header, content = h.request(url, "GET")
        logging.debug("[LaymanAuthLiferay][_getUserInfo] response header: %s"% header)
        logging.debug("[LaymanAuthLiferay][_getUserInfo] response content: %s"% content)

        # TODO: check the header

        # Return the response
        return content

    # Parse the reply from Slavek's service
    # Parsing in separate function makes it testable 
    def _parseUserInfo(self, content):

        # Process the response
        try:
            self.authJson = json.loads(content)

            # Role names: lower() and spaces
            if self.authJson["userInfo"] and self.authJson["userInfo"]["roles"]:
                roles = self.authJson["userInfo"]["roles"]
                for rr in roles:
                    rr["roleName"] = rr["roleName"].lower()
                    rr["roleName"] = "_".join(rr["roleName"].split(' '))
                rolesStr = json.dumps(roles)
                logging.debug("[LaymanAuthLiferay][_parseUserInfo] Roles: '%s'"% rolesStr)

            logging.debug("[LaymanAuthLiferay][_parseUserInfo] Liferay reply successfully parsed")
        except ValueError,e:
            logging.error("[LaymanAuthLiferay][_parseUserInfo] Cannot parse Liferay reply: '%s'"% content)
            raise AuthError(500, "Cannot parse Liferay response [%s] as JSON:%s"% (content,e)) 

        if self.authJson["resultCode"] == "0":
            self.authorised = True
            logging.info("[LaymanAuthLiferay][_parseUserInfo] Authentication successful")
        else:
            logging.error("[LaymanAuthLiferay][_parseUserInfo] Authentication failed: Liferay does not recognise given JSESSIONID")
            raise AuthError(401, "Authentication failed: Liferay does not recognise given JSESSIONID")
Esempio n. 18
0
async def requires_auth(token):
    """Determines if the Access Token is valid
    """
    ####################################################
    # Trying to call this API async, but doesn't work  #
    # Recommend to use redis to store this value       #
    ####################################################
    jsonurl = urllib2.urlopen("https://" + AUTH0_DOMAIN +
                              "/.well-known/jwks.json")

    ####################################################
    # Here the api call originally sync                #
    ####################################################
    # jsonurl = urlopen("https://" + AUTH0_DOMAIN + "/.well-known/jwks.json")

    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    for key in jwks["keys"]:
        if key["kid"] == unverified_header["kid"]:
            rsa_key = {
                "kty": key["kty"],
                "kid": key["kid"],
                "use": key["use"],
                "n": key["n"],
                "e": key["e"]
            }

    if rsa_key:
        try:
            user = jwt.decode(token,
                              rsa_key,
                              algorithms=ALGORITHMS,
                              audience=API_AUDIENCE,
                              issuer="https://" + AUTH0_DOMAIN + "/")
            ###########################################
            print(user)  # Remove this debug log TODO #
            ###########################################

            return User(iss=str(user['iss']),
                        sub=str(user['sub']),
                        aud=str(user['aud']),
                        iat=str(user['iat']),
                        euserp=str(user['exp']),
                        azp=str(user['azp']),
                        scope=str(user['scope']),
                        roles=json.dumps(user['http://roles.ggt/roles']))
        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    "code": "token_expired",
                    "description": "token is expired"
                }, 401)
        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    "code":
                    "invalid_claims",
                    "description":
                    "incorrect claims,"
                    "please check the audience and issuer"
                }, 401)
        except Exception:
            raise AuthError(
                {
                    "code": "invalid_header",
                    "description": "Unable to parse authentication"
                    " token."
                }, 401)

    raise AuthError(
        {
            "code": "invalid_header",
            "description": "Unable to find appropriate key"
        }, 401)
Esempio n. 19
0
    def POST(self, name=None):
        try:
                logging.info("[LayMan][POST] %s"% name)
                params = repr(web.input())
                logging.info("[LayMan][POST] Parameters: %s ... %s"%\
                        (str(params)[:500], str(params)[-500:]))

                global config
                if not self.auth.authorised:
                    logging.error("[LayMan][POST] Unauthorised")
                    raise AuthError(401, "Authorisation failed. Are you logged-in?")

                code = None
                message = None
                origName = name
                name = [d for d in os.path.split(origName) if d]

                if len(name) > 0:

                    # POST "http://localhost:8080/layman/fileman/file.shp"
                    if name[0] == "fileman":
                        from fileman import FileMan
                        fm = FileMan()
                        # Jachyme, what we expect here to receive from the client?
                        # Where is it documented?
                        inpt = web.input(filename={}, newfilename="")
                        newFilename = inpt["newfilename"]
                        if not newFilename:
                            newFilename = inpt["filename"].filename
                        newFilename = self._getTargetFile(newFilename,False)
                        (code, message) = fm.postFile(newFilename, inpt["filename"].file.read())  # FIXME Security: we
                                                                         # shoudl read file size up to X megabytes
                        web.header("Content-type", "text/html")

                    # POST /layman/user
                    # data: {screenName: "user", roles: [{roleTitle, roleName}, {roleTitle, roleName}]}
                    elif name[0] == "user":
                        from userprefs import UserPrefs
                        up = UserPrefs(config)
                        data = web.data()
                        logging.debug(data)
                        (code, message) = up.createUser(userJsonStr=data)

                    # POST "http://localhost:8080/layman/layed?fileName=Rivers.shp&usergroup=RescueRangers"
                    elif name[0] == "layed":
                        from layed import LayEd
                        le = LayEd(config)
                        inpt = web.input(usergroup=None)
                        if not inpt.fileName:
                            raise LaymanError(
                                400, "'fileName' parameter missing")
                        fileName = inpt.fileName
                        fsUserDir = self.auth.getFSUserDir()
                        fsGroupDir = self.auth.getFSGroupDir(inpt.usergroup)
                        dbSchema = self.auth.getDBSchema(inpt.usergroup)
                        gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup)
                        crs = inpt.crs # native crs
                        tsrs = inpt.tsrs # target srs
                        cpg = inpt.cpg # code page

                        secureLayer = True
                        if "secureLayer" in inpt:
                            if inpt.secureLayer.lower() == "false":
                                secureLayer = False

                        (code, layerName, message) = le.importAndPublish(fsUserDir, fsGroupDir,
                                                     dbSchema, gsWorkspace,
                                                     fileName, crs, tsrs, cpg, inpt, secureLayer)
                        # Set Location header
                        if code == 201 and layerName is not None:
                            location = layerName # TODO: provide full URI here             
                            web.header("Location", location)

                    elif name[0] == "publish" or name[0] == "data":
                        from layed import LayEd
                        le = LayEd(config)
                        inpt = web.input()

                        # Obligatory parameters
                        if not "schema" in inpt:
                            raise LaymanError(
                                400, "'schema' parameter missing")
                        if not "view" in inpt:
                            raise LaymanError(
                                400, "'view' parameter missing")
                        if not "crs" in inpt:
                            raise LaymanError(
                                400, "'crs' parameter missing")

                        viewName = inpt.view
                        dbSchema = self.auth.getDBSchema(inpt.schema)
                        gsWorkspace = self.auth.getGSWorkspace(inpt.schema)
                        crs = inpt.crs

                        secureLayer = True
                        if "secureLayer" in inpt:
                            if inpt.secureLayer.lower() == "false":
                                secureLayer = False

                        # Optional parameters
                        styleName = None
                        styleWs = None                        
                        if "style" in inpt:
                            styleName = inpt.style
                        if "style_ws" in inpt:
                            styleWs = inpt.style_ws

                        (code, layerName, message) = le.publishFromDbToGs(dbSchema, 
                                                            viewName, 
                                                            gsWorkspace, 
                                                            crs, inpt, styleName, styleWs, secureLayer)

                        # Set Location header
                        if code == 201 and layerName is not None:
                            location = layerName # TODO: provide full URI here             
                            web.header("Location", location)

                    else:
                        (code, message) = self._callNotSupported(restMethod="POST",
                                                                 call=origName)

                else:
                    (code, message) = self._callNotSupported(restMethod="POST", call=origName)

                success = self._setReturnCode(code)
                retval  = self._jsonReply(code, message, success)
                return retval

        except LaymanError as le:
            return self._handleLaymanError(le)

        except Exception as e:
            return self._handleException(e)
Esempio n. 20
0
    def DELETE(self, name=None):

        try:
                logging.info("[LayMan][DELETE] %s"% name)
                params = repr(web.input())
                logging.info("[LayMan][DELETE] Parameters: %s ... %s"%\
                        (str(params)[:500], str(params)[-500:]))

                if not self.auth.authorised:
                    logging.error("[LayMan][DELETE] Unauthorised")
                    raise AuthError(401, "Authorisation failed. Are you logged-in?")

                code = 404    # 200, 404...
                message = "Call not supported: DELETE "+name+" Please check the API doc or report a bug if appropriate."

                path = [d for d in name.split(os.path.sep) if d]
                if len(name) > 0:

                    if path[0] != "fileman" and not self.auth.canDelete():
                            logging.error("[LayMan][DELETE] Only admin can DELETE")
                            raise AuthError(401, "Authorisation failed. Only Administrator can delete")

                    # /fileman/file.shp"
                    if path[0] == "fileman":
                            from fileman import FileMan
                            fm = FileMan()
                            fileName = name[8:]
                            (code, message) = fm.deleteFile(self._getTargetFile(path[-1]))

                    # /user/<username>
                    elif path[0] == "user" and len(path) == 2:
                        userName = path[1]
                        from userprefs import UserPrefs
                        up = UserPrefs(config)
                        (code, message) = up.deleteUser(userName)

                    # /layed/<layer>
                    elif path[0] == "layed" and len(path) == 2:
                        from layed import LayEd
                        le = LayEd()
                        layerName = path[1]
                        inpt = web.input(usergroup=None)
                        
                        deleteTable = True
                        if "deleteTable" in inpt:
                            if inpt["deleteTable"].lower() == "false":
                                deleteTable = False
                        
                        gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup)
                        dbSchema    = self.auth.getDBSchema(inpt.usergroup)
                        logging.info("[LayMan][DELETE] Delete layer '%s'"% layerName )
                        logging.info("[LayMan][DELETE] Delete from workspace '%s'"% gsWorkspace)
                        (code, message) = le.deleteLayer(gsWorkspace, layerName, dbSchema, deleteTable)

                    # /publish/<layer>
                    elif path[0] == "publish" and len(path) == 2:
                        from layed import LayEd
                        le = LayEd()
                        layerName = path[1]
                        inpt = web.input()
                        if not "schema" in inpt:
                            raise LaymanError(
                                400, "'schema' parameter missing")

                        gsWorkspace = self.auth.getGSWorkspace(inpt.schema)
                        dbSchema    = self.auth.getDBSchema(inpt.schema)
                        logging.info("[LayMan][DELETE] Delete layer '%s'"% layerName )
                        logging.info("[LayMan][DELETE] Delete from workspace '%s'"% gsWorkspace)
                        (code, message) = le.deleteLayer(gsWorkspace, layerName, dbSchema, deleteTable=False)

                success = self._setReturnCode(code)
                retval  = self._jsonReply(code, message, success)
                return retval

        except LaymanError as le:
            return self._handleLaymanError(le)

        except Exception as e:
            return self._handleException(e)
Esempio n. 21
0
    def PUT(self, name=None):

        try:
                logging.info("[LayMan][PUT] %s"% name)
                params = repr(web.input())
                logging.info("[LayMan][PUT] Parameters: %s ... %s"%\
                        (str(params)[:500], str(params)[-500:]))

                global config
                if not self.auth.authorised:
                    logging.error("[LayMan][PUT] Unauthorised")
                    raise AuthError(401, "Authorisation failed. Are you logged-in?")

                code = 404    # 200, 404...
                message = "Call not supported: PUT "+name+" Please check the API doc or report a bug if appropriate."

                path = [d for d in name.split(os.path.sep) if d]

                # PUT "http://localhost:8080/layman/fileman/file.shp"
                if path[0]  == "fileman":
                    from fileman import FileMan
                    fm = FileMan()
                    fileName = path[-1]
                    data = web.data()
                    (code, message) = fm.putFile(self._getTargetFile(
                                                 fileName), data)

                # PUT /layman/user/
                # data: {screenName: "user", roles: [{roleTitle, roleName}, {roleTitle, roleName}]}
                elif path[0] == "user":
                    from userprefs import UserPrefs
                    up = UserPrefs(config)
                    data = web.data()
                    logging.debug(data)
                    (code, message) = up.updateUser(userJsonStr=data)

                elif path[0] == "geoserver":
                    from layed.gsconfig import GsConfig

                    # /geoserver/style/style_name
                    if path[1] == "style":
                        #ws = None
                        #if len(path) > 3:
                        #    ws = path[-2]
                        gsc = GsConfig()
                        # If PUT Style fails, gsconfig throws an exception
                        try:
                            gsc.putStyle(path[-1], web.data())
                            (code, message) = (200, "PUT Style OK")
                        except Exception as e:
                            code = 500
                            message = "PUT Style failed: " + str(e)

                # /layed/config/<layer>?usergroup=FireBrigade
                elif path[0] == "layed" and len(path) == 2:
                    from layed import LayEd
                    le = LayEd()
                    layerName = path[1]
                    inpt = web.input(usergroup=None)
                    gsWorkspace = self.auth.getGSWorkspace(inpt.usergroup)
                    data = web.data()
                    data = json.loads(data)  # string -> json

                    usergroup = inpt.usergroup
                    if (not usergroup) and ("usergroup" in data.keys()):
                        logging.debug("[LayMan][PUT] Usergroup not provided in params, but given in data: %s"% data["usergroup"])
                        usergroup = data["usergroup"]

                    fsUserDir = self.auth.getFSUserDir()
                    fsGroupDir = self.auth.getFSGroupDir(usergroup)
                    dbSchema = self.auth.getDBSchema(usergroup)
                    gsWorkspace = self.auth.getGSWorkspace(usergroup)

                    (code, message) = le.putLayerConfig(gsWorkspace,
                                                        layerName, data,
                                                        fsUserDir, fsGroupDir,
                                                        dbSchema)

                success = self._setReturnCode(code)
                retval = self._jsonReply(code, message, success)
                return retval

        except LaymanError as le:
            return self._handleLaymanError(le)

        except Exception as e:
            return self._handleException(e)