def ocrun(self): logger.debug('') try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) args = cherrypy.request.json if type(args) is not dict: return Results.error(message='invalid parameters') # appname must exists appname = args.get('image') if type(appname) is not str: return Results.error('Missing parameter image') # add lang to user dict self.LocaleSettingsLanguage(user) try: result = oc.od.composer.openapp(auth, user, args) except Exception as e: return Results.error(str(e)) return Results.success(result=result)
def rtp_stream(self, action=lambda x: x): try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) if not settings.webrtc_enable: return Results.error( message='WebRTC is disabled in configuration file') if services.webrtc is None: return Results.error(message='no WebRTC configuration found') appname = None args = cherrypy.request.json if type(args) is dict: appname = args.get('app') desktop = oc.od.composer.finddesktop_quiet(authinfo=auth, userinfo=user, appname=appname) if desktop is None: return Results.error(message='desktop not found') try: stream = action(desktop.name) except Exception as e: return Results.error('webrtc stream failed ' + str(e)) return Results.success(result=stream)
def _getcollection(self, dbname, key): value = None if all([dbname, key]): value = services.datastore.getcollection(dbname, key) if value is None: return Results.error('key:%s not found' % key, 404) return Results.success(result=value)
def logout(self, redirect_uri=None): """ Logout a connected user, remove the desktop only if anonymous remove all homedir data remove all cookies (by setting empty value) Args: redirect_uri (str): redirect uri Returns: JSON Results """ bReturn = None args = cherrypy.request.json if services.auth.isidentified: user = services.auth.user auth = services.auth.auth # remove the pod/container if oc.od.composer.removedesktop(auth, user, args) is False: bReturn = Results.error( message='removedesktop failed' ) # Always remove all http cookies services.auth.logout() bReturn = Results.success() else: bReturn = Results.error( message='invalid user credentials' ) return bReturn
def get(self): # Check auth try: (auth, user ) = self.validate_env() except Exception as e: self.logger.error( e ) return Results.error( message=str(e) ) arguments = cherrypy.request.json if type(arguments) is not dict : return Results.error( message='invalid parameters' ) userid = user.userid value = None key = arguments.get('key') if all([userid, key]): self.logger.debug('getstoredvalue userid:%s key:%s', str(userid), str(key) ) value = services.datastore.getstoredvalue(userid, key) if value is None: return Results.error('value not found: userid = %s, key = %s' % (userid,key), 404) return Results.success(result=value)
def list(self): logger.info('') try: (auth, user ) = self.validate_env() except Exception as e: logger.error( e ) return Results.error( message=str(e) ) printers = [] logger.debug('self.getclientlocation') location = self.getclientlocation( auth ) if type(location) is oc.od.locator.ODLocation and \ location.resolved and location.site : logger.debug('location is resolved') # find the auth provider logger.debug('looking for the auth provider') provider=services.auth.findprovider( name=auth.data.get('domain') ) # build the ldap filter logger.debug('build the ldap filter') sitefilter = '(location=' + location.site + '*)' logger.debug('ldap filter %s', sitefilter) # run query to ldap server printers=provider.listprinter( sitefilter ) else: # return empty data, location is not found # we do know where the user is and # we can not query the activedirectory to find printers pass return Results.success(result=printers)
def listenable(self): logger.debug('') try: (auth, user ) = self.validate_env() except Exception as e: logger.error( e ) return Results.error( message=str(e) ) try: name=auth.data.get('domain') except Exception: message='only activedirectory printer are supported' logger.error( message ) return Results.error(message=message) printerenabledlist = [] provider=services.auth.findprovider( name ) printerctl = self.createprinterctl( auth, user ) for printername in printerctl.list(): if printername not in settings.printercupsembeddedList: printercn = printerctl.describe(printername).get('Description') if printercn: printerfilter = '(cn=' + printercn + ')' logger.debug('filter %s', printerfilter) # run query to ldap server printerentry=provider.listprinter( printerfilter ) if len(printerentry) == 1: # Only one printer should be found printerenabledlist.append(printerentry[0]) return Results.success(result=printerenabledlist)
def refreshtoken(self): if services.auth.isidentified: user = services.auth.user auth = services.auth.auth expire_in = oc.od.settings.jwt_config_user.get('exp') services.auth.update_token( auth=auth, user=user, roles=None, expire_in=expire_in ) services.accounting.accountex('login', 'refreshtoken') return Results.success("Authentication successful", {'expire_in': expire_in } ) return Results.error(message='Invalid user')
def listcontainer(self): try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) result = oc.od.composer.listContainerApp(auth, user) if type(result) is list: return Results.success(result=result) return Results.error('failed to read container list')
def getlocation(self): logger.debug('') try: (auth, user) = self.validate_env() except Exception as e: logger.error( e ) return Results.error( message=str(e) ) location = oc.od.user.getlocation( auth ) return Results.success(result=location)
def getlogs(self): try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) logs = oc.od.composer.logdesktop(auth, user) if logs: return Results.success(result=logs) return Results.error('failed to read log')
def isauthenticated(self): """ Return a result object with auth status Args: None Returns: Results object if user is authenticated """ return Results.success(result=services.auth.isauthenticated)
def getuserapplist(self): logger.debug('') try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) # list all applications allowed for this user (auth) applist = services.apps.user_applist(auth) # get the default application list from the config file userapplist = settings.get_default_applist() userapplist += applist return Results.success(result=userapplist)
def getmessageinfo(self): try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) message = '' if user.userid: logger.debug('getmessageinfo::popflush(%s)', user.userid) message = services.messageinfo.popflush(user.userid) logger.debug('getmessageinfo %s is %s', str(user.userid), str(message)) else: logger.debug('getmessageinfo warning userid is None') return Results.success(message, result={'message': message})
def labels(self): """[summary] Returns: [json]: [Results array of labels if auth set] """ self.logger.debug('') res = None if services.auth.isidentified: auth = services.auth.auth labels = [] if auth.data and type( auth.data.get('labels') ) is dict : for k in auth.data.get('labels').keys(): labels.append( str(k) ) res = Results.success( result=labels) else: res = Results.error( message='invalid user credentials' ) return res
def issue(self): """[summary] """ try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) arguments = cherrypy.request.json myjira = oc.od.tracker.jiraclient() summary = arguments.get('summary', 'summary') description = arguments.get('description', 'description') issuetype = arguments.get('issue', {'name': 'Bug'}) new_issue = myjira.issue(description=description, summary=summary, issuetype=issuetype) return Results.success(result=new_issue)
def removecontainer(self): try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) args = cherrypy.request.json if type(args) is not dict: return Results.error(message='invalid parameters') containerid = args.get('containerid') if type(containerid) is not str: return Results.error(message='invalid parameter containerid') result = oc.od.composer.removeContainerApp(auth, user, containerid) if result is not None: return Results.success(result=result) return Results.error('failed to remove container')
def remove(self): # # get the printername json paramater printername = cherrypy.request.json.get('printerName') if type(printername) is not str or len(printername)<1: raise WebAppError('Invalid argument: printerName') try: (auth, user ) = self.validate_env() except Exception as e: logger.error( e ) return Results.error( message=str(e) ) try: domain=auth.data.get('domain') except Exception: return Results.error(message='only activedirectory printers are supported') # Do not trust user inpout # Only trust LDAP data # Run a secure query to ldap to check that printer exists # value is escaped in list_ldap_printer printers = self.list_ldap_printer( attribut='printerName', value=printername, domain=domain) if type(printers) is not list: # Only one printer should be found return Results.error(message='Printer not found') if len(printers) != 1: # Only one printer should be found return Results.error(message='Printer not found or too much data found') printer = printers[0] try: trustedprintername = printer.get('printerName') logger.debug( 'removing printer name found in directory %s', trustedprintername ) self.createprinterctl( auth, user ).remove( trustedprintername ) except Exception as e: logger.error( e ) return Results.error( message=str(e) ) return Results.success()
def disconnect(self): """ Disconnect a connected user, remove ONLY all cookies (by setting empty value) Keep desktop running Args: None Returns: JSON Results """ bReturn = None if services.auth.isidentified: # Always remove all http cookies services.auth.logout() bReturn = Results.success() else: bReturn = Results.error( message='invalid user credentials' ) return bReturn
def refreshdesktoptoken(self): logger.debug('') try: (auth, user) = self.validate_env() except Exception as e: logger.error(e) return Results.error(message=str(e)) appname = None args = cherrypy.request.json if type(args) is dict: appname = args.get('app') preferednodehostname = services.auth.user.get('nodehostname') if preferednodehostname is None: self.logger.debug('services.auth.nodehostname is None') preferednodehostname = cherrypy.request.headers.get( 'Prefered-Nodename') desktop = oc.od.composer.finddesktop_quiet(authinfo=auth, userinfo=user, appname=appname) if desktop is None: return Results.error('refreshdesktoptoken failed') # This case should only exist if a desktop is running twice on the same host # twice mode standalone in docker mode and kubernetes mode if desktop.internaluri is None: return Results.error( 'refreshdesktoptoken Desktop internaluri is None, unreachable') # build new jwtdesktop jwtdesktoptoken = services.jwtdesktop.encode(desktop.internaluri) logger.info('jwttoken is %s -> %s ', desktop.internaluri, jwtdesktoptoken) return Results.success( result={ 'authorization': jwtdesktoptoken, # desktop.ipAddr 'expire_in': services.jwtdesktop.exp() })
def deleteacl(self): # Check auth try: (auth, user ) = self.validate_env() except Exception as e: self.logger.error( e ) return Results.error( message=str(e) ) arguments = cherrypy.request.json if type(arguments) is not dict: return Results.error('bad request invalid parameters') dbname = 'acl' key = arguments.get('key') value = arguments.get('value') if all([dbname, key]) and services.datastore.deletestoredvalue(dbname, key, value) is True: return Results.success() return Results.error('set data error')
def set(self): # Check auth try: (auth, user ) = self.validate_env() except Exception as e: self.logger.error( e ) return Results.error( message=str(e) ) arguments = cherrypy.request.json if type(arguments) is not dict : return Results.error( message='invalid parameters' ) userid = user.userid key = arguments.get('key') value = arguments.get('value') logger.debug('setstoredvalue userid:%s key:%s value:%s', str(userid), str(key), str(value) ) if all([userid, key]): if services.datastore.setstoredvalue(userid, key , value) is True: return Results.success() else: Results.error('setstoredvalue failed') else: Results.error('invalid params')
def add(self): logger.debug('') # # get the cn json paramater try: cn = cherrypy.request.json.get('cn') if not cn: return Results.error( message='Argument not set: cn') except Exception as e: logger.error( e ) return Results.error( message=str(e) ) # valide env user and auth try: (auth, user ) = self.validate_env() except Exception as e: logger.error( e ) return Results.error( message=str(e) ) try: domain=auth.data.get('domain') except Exception: return Results.error(message='only activedirectory printers are supported') # value is escaped in list_ldap_printer printers = self.list_ldap_printer( attribut='cn', value=cn, domain=domain) if type(printers) is not list: # Only one printer should be found return Results.error(message='Printer not found') if len(printers) != 1: # Only one printer should be found return Results.error(message='Printer not found or too much data found, expected only one') printer = printers[0] myOrchestrator = oc.od.composer.selectOrchestrator() try: # network printers use Samba share by default credentials = myOrchestrator.findSecretByUser(auth, user, 'cifs') except Exception as e: self.logger.error( e ) return Results.error( message=str(e) ) try: # use only LDAP attribut # NEVER use user input data self.createprinterctl( auth, user ).add( name = printer.get('printerName'), cn = printer.get('cn'), uncname = printer.get('uNCName'), location = printer.get('location'), language = printer.get('printerLanguage'), options = printer.get('options', {}), printMediaReady = printer.get('printMediaReady'), username = credentials.get('username'), password = credentials.get('password'), domain = credentials.get('domain') ) return Results.success() except Exception as e: self.logger.error( e ) return Results.error( message=str(e) )
def _launchdesktop(self, preferednodehostname, auth, user, args): nodehostname = preferednodehostname appname = args.get('app') messageinfo = services.messageinfo.start(user.userid, 'Looking for your desktop') try: ipaddr = oc.cherrypy.getclientipaddr() args['usersourceipaddr'] = ipaddr desktop = oc.od.composer.opendesktop(nodehostname, auth, user, args) if desktop is None: return Results.error('Desktop creation failed') if desktop.internaluri is None: return Results.error('Desktop URI is None, creation failed') # update internal dns entry # only if we use an external direct access # desktop_fqdn = services.internaldns.update_dns( desktop.id, desktop.ipAddr) # logger.info('New entry is dns %s->%s ', desktop_fqdn, desktop.ipAddr ) # In kubernetes mode change the desktop.ipAddr # to IpAddr.desktop.abcdesktop.svc.cluster.local # example # If th Pod IPAddr is 10-1-1-85 # 10-1-1-85.desktop.abcdesktop.svc.cluster.local # desktoptarget = self.build_desktop_internal_fqdn( desktop.ipAddr ) jwtdesktoptoken = services.jwtdesktop.encode(desktop.internaluri) logger.info('jwttoken is %s -> %s ', desktop.internaluri, jwtdesktoptoken) logger.info('Service is running on node %s', str(desktop.nodehostname)) datadict = { **user, 'provider': auth.providertype, 'date': datetime.datetime.utcnow().isoformat(), 'useragent': cherrypy.request.headers.get('User-Agent', None), 'ipaddr': ipaddr, 'node': desktop.nodehostname } if appname: datadict['type'] = 'metappli' datadict['app'] = appname else: datadict['type'] = 'desktop' services.datastore.addtocollection(databasename=user.userid, collectionname='loginHistory', datadict=datadict) expire_in = services.jwtdesktop.exp() return Results.success( result={ 'target_ip': oc.lib.get_target_ip_route(desktop.ipAddr), 'vncpassword': desktop.vncPassword, 'authorization': jwtdesktoptoken, # contains desktop.uri (ipaddr) 'websocketrouting': oc.od.settings.websocketrouting, 'websockettcpport': oc.od.settings.desktopservicestcpport['x11server'], 'expire_in': expire_in }) finally: messageinfo.stop() # Stop message info log
def _addtocollection(self, dbname, key, value): if all([dbname, key]) and services.datastore.addtocollection(dbname, key, value) is True: return Results.success() else: return Results.error( message='addtocollection failed')
def auth(self): """ authentificate a user with json http request parameters Args: None use implicit json http Returns: JSON Result Results success if success set auth jwt cookie result={'userid': response.result.user.userid, 'name': response.result.user.name, 'provider': response.result.auth.providertype, 'expire_in': expire_in } return Results.success else raise cherrypy.HTTPError(400) invalid parameters raise cherrypy.HTTPError(401) invalid credentials """ self.logger.debug('auth call') cherrypy.response.timeout = 180 args = cherrypy.request.json # services.auth.isauthenticated is False if type(args) is not dict: raise cherrypy.HTTPError(400) # Check if provider is set if not args.get('provider'): raise cherrypy.HTTPError(400) # do login self.logger.info( 'event:start services.auth.login' ) response = services.auth.login(**args) self.logger.info( 'event:stop services.auth.login' ) if not response.success: services.accounting.accountex('login', 'failed') raise cherrypy.HTTPError(401, response.reason) services.accounting.accountex('login', 'success') services.accounting.accountex('login', response.result.auth.providertype ) # Explicit Manager contains credentials # if the user have to access authenticated external ressources # this is the only one request whicj contains users credentials # Build now auth secret for postponed usage if type(response.mgr) is oc.auth.authservice.ODExplicitAuthManager : # prepare external ressource access with current credentials # build secret for kubernetes to use the desktop flexvolume drivers # Only used if mode is kubernetes, nothing to do in docker standalone self.logger.info( 'event:start oc.od.composer.prepareressources' ) oc.od.composer.prepareressources( response.result.auth, response.result.user ) self.logger.info( 'event:stop oc.od.composer.prepareressources' ) self.logger.info( 'event:start oc.od.settings.jwt_config_user' ) expire_in = oc.od.settings.jwt_config_user.get('exp') services.auth.update_token( auth=response.result.auth, user=response.result.user, roles=response.result.roles, expire_in=expire_in ) self.logger.info( 'event:stop oc.od.settings.jwt_config_user' ) return Results.success( message="Authentication successful", result={'userid': response.result.user.userid, 'name': response.result.user.name, 'provider': response.result.auth.providertype, 'expire_in': expire_in })