Пример #1
0
def emailEffect(effect, info):
	"""Email Effect

	Sends the effect to a developer so they are aware of the error

	Arguments:
		effect {Services.Effect} -- The effect to send
		info {dict} -- Info about the request

	Returns:
		None
	"""

	# Try to send an e-mail
	oEffect = Services.create('communications', 'email', {
		"_internal_": Services.internalKey(),
		"from": "noreply@%s" % Conf.get(("domain", "primary")),
		"subject": "external error",
		"text_body": "Info: %s\nEffect: %s" % (str(info), str(effect)),
		"to": Conf.get(("email", "errors"))
	})

	# If there's an error
	if oEffect.errorExists():
		raise oEffect
Пример #2
0
def init(dbs=[], services={}, templates=False):
	"""Initialise

	Starts up most of the modules needed to support REST and Services

	Arguments:
		dbs (str[]): List of DBs to start up
		services (dict): Dictionary of service name to instance being managed
			by the caller

	Returns:
		REST.Config
	"""

	# Load the config
	Conf.load('config.json')
	sConfOverride = 'config.%s.json' % platform.node()
	if os.path.isfile(sConfOverride):
		Conf.load_merge(sConfOverride)

	# Add the global prepend
	Record_Base.dbPrepend(Conf.get(("mysql", "prepend"), ''))

	# Go through the list of DBs requested
	for s in dbs:
		Record_MySQL.addHost(s, Conf.get(("mysql", "hosts", s)))

	# Init the Sesh module
	Sesh.init(Conf.get(("redis", "primary")))

	# Create the REST config instance
	oRestConf = REST.Config(Conf.get("rest"))

	# Set verbose mode if requested
	if 'VERBOSE' in os.environ and os.environ['VERBOSE'] == '1':
		Services.verbose()

	# Get all the services
	dServices = {k:None for k in Conf.get(('rest', 'services'))}

	# Overwrite those passed in
	for n,o in services.items():
		dServices[n] = o

	# Register all services
	Services.register(dServices, oRestConf, Conf.get(('services', 'salt')))

	# Init Templates
	if templates:
		Templates.init(templates)

	# Return the REST config
	return oRestConf
Пример #3
0
def init(verbose=False):
    """Init

	Called to initialize the service

	Args:
		verbose (bool): Optional verbose argument
			if set to True, the service will print out what's going on
	"""

    # Import the global redis instance
    global _r, _r_pubsub, _verbose

    # Create a new Redis instance
    _r = StrictRedis(**Conf.get(('redis', 'sync'), {
        "host": "localhost",
        "port": 6379,
        "db": 1
    }))

    # Get the pubsub instance
    _r_pubsub = _r.pubsub()

    # Subscribe to an empty channel just to get things started
    _r_pubsub.subscribe('sync')

    # Set the verbose flag
    _verbose = verbose and True or False
Пример #4
0
    def initialise(self):
        """Initialise

		Initialises the communications service

		Returns:
			None
		"""

        # Get the default from
        self.fromDefault = Conf.get(('email', 'from'))

        # Get the method for sending emails
        self.emailMethod = Conf.get(('email', 'method'))

        # If it's invalid
        if self.emailMethod not in ['direct', 'queue']:
            raise ValueError('Communications.emailMethod', self.emailMethod)
Пример #5
0
    def initialise(self):
        """Initialise

		Initialises the instance and returns itself for chaining

		Returns:
			Auth
		"""

        # Init the sync module
        Sync.init(
            Conf.get(('redis', 'sync'), {
                "host": "localhost",
                "port": 6379,
                "db": 1
            }))
Пример #6
0
def verify(id, key):

	# Contact the auth service to verify the key
	oEffect = Services.update('auth', 'thrower/verify', {
		"_internal_": Services.internalKey(),
		"id": id,
		"verify": key
	})

	# If there's an error
	if oEffect.errorExists():
		print(oEffect)
		emailEffect(oEffect, {"request":"verify", "id": id, "key":key})
		return show500()

	# Redirect to main site
	dConf = Conf.get("domain")
	bottle.redirect("%s://%s/#verified" % (
		dConf['protocol'],
		dConf['primary']
	))
Пример #7
0
__author__ = "Chris Nasr"
__copyright__ = "OuroborosCoding"
__version__ = "1.0.0"
__maintainer__ = "Chris Nasr"
__email__ = "*****@*****.**"
__created__ = "2019-04-18"

# Pip imports
from FormatOC import Tree
from RestOC import Conf, Record_ReDB

# Match structure and config
_mdMatchConf = Record_ReDB.Record.generateConfig(
    Tree.fromFile('../json/definitions/watl/match.json'), 'rethinkdb',
    Conf.get(("rethinkdb", "axegains")))

# MatchStats structure and config
_mdMatchStatsConf = Record_ReDB.Record.generateConfig(
    Tree.fromFile('../json/definitions/watl/match_stats.json'), 'rethinkdb',
    Conf.get(("rethinkdb", "axegains")))

# Practice structure and config
_mdPracticeConf = Record_ReDB.Record.generateConfig(
    Tree.fromFile('../json/definitions/watl/practice.json'), 'rethinkdb',
    Conf.get(("rethinkdb", "axegains")))

# PracticePattern structure and config
_mdPracticePatternConf = Record_ReDB.Record.generateConfig(
    Tree.fromFile('../json/definitions/watl/practice_pattern.json'),
    'rethinkdb', Conf.get(("rethinkdb", "axegains")))
Пример #8
0
__maintainer__	= "Chris Nasr"
__email__		= "*****@*****.**"
__created__		= "2019-04-18"

# Python imports
import os, platform

# Pip imports
from RestOC import Conf, Record_Base, Record_ReDB, REST, \
					Services, Sesh

# App imports
from apps.watl import Watl

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
	Conf.load_merge(sConfOverride)

# Add the global prepend and primary host to rethinkdb
Record_Base.dbPrepend(Conf.get(("rethinkdb", "prepend"), ''))
Record_ReDB.addHost('primary', Conf.get(("rethinkdb", "hosts", "primary")))

# Init the Sesh module
Sesh.init(Conf.get(("redis", "session")))

# Create the REST config instance
oRestConf = REST.Config(Conf.get("rest"))

# Set verbose mode if requested
Пример #9
0
# coding=utf8
""" Install Services

Adds global tables
"""

# Python imports
import os, platform

# Framework imports
from RestOC import Conf, Record_ReDB

# Services
from apps import auth, natf

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
    Conf.load_merge(sConfOverride)

# Add primary host
Record_ReDB.addHost('primary', Conf.get(("rethinkdb", "hosts", "primary")))

# Add the DB
Record_ReDB.dbCreate(Conf.get(("rethinkdb", "db"), "axegains"))

# Install
auth.Auth.install()
natf.Natf.install()
Пример #10
0
    def passwdForgot_create(self, data):
        """Password Forgot (Generate)

		Creates the key that will be used to allow a user to change their
		password if they forgot it

		Arguments:
			data {dict} -- Data sent with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['email'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Look for the thrower by email
        oThrower = Thrower.get(data['email'], index='email', limit=1)
        if not oThrower:
            return Services.Effect(True)

        # Is there already a key in the thrower?
        if 'forgot' in oThrower and 'regenerate' not in data:

            # Is it not expired?
            if oThrower['forgot']['expires'] > int(time()):
                return Services.Effect(True)

        # Update the thrower with a timestamp (for expiry) and the key
        sKey = StrHelper.random(32, '_0x')
        oThrower['forgot'] = {"expires": int(time()) + 300, "key": sKey}
        if not oThrower.save(changes=False):
            return Services.Effect(error=1103)

        # Get the domain config
        dConf = Conf.get("domain")

        # Forgot email template variables
        dTpl = {
            "key":
            sKey,
            "url":
            "%s://%s/#forgot=%s" % (dConf['protocol'], dConf['primary'], sKey)
        }

        # Email the user the key
        oEffect = Services.create(
            'communications', 'email', {
                "_internal_":
                Services.internalKey(),
                "html_body":
                Templates.generate('email/forgot.html', dTpl,
                                   oThrower['locale']),
                "subject":
                Templates.generate('email/forgot_subject.txt', {},
                                   oThrower['locale']),
                "to":
                data['email'],
            })
        if oEffect.errorExists():
            return oEffect

        # Return OK
        return Services.Effect(True)
Пример #11
0
# Service imports
from services.primary import Primary

# Local imports
from . import init

# Init the REST info
oRestConf = init(
	dbs=['primary'],
	services={'primary':Primary()},
	templates='templates'
)

# Init the SMTP module
SMTP.init(**Conf.get(('email', 'smtp')))

# Create the HTTP server and map requests to service
REST.Server({

	# Clients
	"/client": {"methods": REST.ALL, "session": True},
	"/clients": {"methods": REST.READ, "session": True},

	# Companies
	"/company": {"methods": REST.READ | REST.UPDATE, "session": True},

	# Invoices
	"/invoice": {"methods": REST.CREATE | REST.READ, "session": True},
	"/invoice/pdf": {"methods": REST.READ, "session": True},
	"/invoices": {"methods": REST.READ, "session": True},
Пример #12
0
# Import python modules
from collections import OrderedDict
import os
import platform
import signal
import threading

# Import pip modules
from gevent import monkey
monkey.patch_all()
from geventwebsocket import Resource, WebSocketServer
from RestOC import Conf, REST

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
    Conf.load_merge(sConfOverride)

# Import service modules
from . import init as wsInit, redisThread, signalCatch, SyncApplication

# If verbose mode is requested
verbose = False
if 'AXE_VERBOSE' in os.environ and os.environ['AXE_VERBOSE'] == '1':
    verbose = True

# Catch SIGNTERM and
signal.signal(signal.SIGINT, signalCatch)
signal.signal(signal.SIGTERM, signalCatch)
Пример #13
0
__author__ = "Chris Nasr"
__copyright__ = "OuroborosCoding"
__version__ = "1.0.0"
__created__ = "2018-11-17"

# Python imports
import os, platform

# Pip imports
from RestOC import Conf, REST, Services, SMTP

# App imports
from apps.communications import Service as Communications

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
	Conf.load_merge(sConfOverride)

# Init the SMTP module
SMTP.init(**Conf.get(('email', 'smtp')))

# Create the REST config instance
oRestConf = REST.Config(Conf.get("rest"))

# Set verbose mode if requested
if 'AXE_VERBOSE' in os.environ and os.environ['AXE_VERBOSE'] == '1':
	Services.verbose()

# Register the Services that will be accessible
Пример #14
0
    def throwerEmail_update(self, data, sesh):
        """Thrower Email

		Changes the email for the current signed in user

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the user

		Returns:
			Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['email', 'email_passwd'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the thrower
        oThrower = Thrower.get(sesh['thrower']['_id'])
        if not oThrower:
            return Services.Effect(error=1104)

        # Validate the password
        if not oThrower.passwordValidate(data['email_passwd']):
            return Services.Effect(error=(1001, [('email_passwd', 'invalid')]))

        # Make sure the email is valid structurally
        if not _emailRegex.match(data['email']):
            return Services.Effect(error=(1001, [('email', 'invalid')]))

        # Look for someone else with that email
        dThrower = Thrower.get(data['email'], index='email', raw=['_id'])
        if dThrower:
            return Services.Effect(error=(1206, data['email']))

        # Update the email and verified fields
        try:
            oThrower['email'] = data['email']
            oThrower['verified'] = StrHelper.random(32, '_0x')
        except ValueError as e:
            return Services.Effect(error=(1001, e.args[0]))

        # Update the thrower
        oThrower.save(changes={"creator": sesh['thrower']['_id']})

        # Send en e-mail for verification
        dConf = Conf.get("domain")
        sURL = "%s://external.%s/verify/%s/%s" % (
            dConf['protocol'], dConf['primary'], oThrower['_id'],
            oThrower['verified'])
        oEffect = Services.create(
            'communications', 'email', {
                "_internal_":
                Services.internalKey(),
                "html_body":
                Templates.generate('email/verify.html', {"url": sURL},
                                   oThrower['locale']),
                "subject":
                Templates.generate('email/verify_subject.txt', {},
                                   oThrower['locale']),
                "to":
                data['email'],
            })
        if oEffect.errorExists():
            return oEffect

        # Return OK
        return Services.Effect(True)
Пример #15
0
    def signup_create(self, data):
        """Signup

		Creates a new user on the system

		Arguments:
			data {dict} -- The data passed to the request

		Returns:
			Result
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['alias', 'passwd'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Make sure the email is valid structurally
        if 'email' in data and not _emailRegex.match(data['email']):
            return Services.Effect(error=(1001, [('email', 'invalid')]))

        # Make sure the password is strong enough
        if not Thrower.passwordStrength(data['passwd']):
            return Services.Effect(error=1204)

        # Look for someone else with that alias
        dThrower = Thrower.get(data['alias'], index='alias', raw=['_id'])
        if dThrower:
            return Services.Effect(error=(1200, data['alias']))

        # If an e-mail was passed
        if 'email' in data:

            # Look for someone else with that email
            dThrower = Thrower.get(data['email'], index='email', raw=['_id'])
            if dThrower:
                return Services.Effect(error=(1206, data['email']))

        # If no language was passed
        if 'locale' not in data:
            data['locale'] = 'en-US'

        # Init the thrower data
        dThrower = {
            "_created": int(time()),
            "alias": data['alias'],
            "locale": data['locale'],
            "org": 'org' in data and data['org'] or 'natf',
            "passwd": Thrower.passwordHash(data['passwd']),
            "verified": StrHelper.random(32, '_0x')
        }

        # If there's an email
        if 'email' in data:
            dThrower['email'] = data['email']
            dThrower['verified'] = StrHelper.random(32, '_0x')
        else:
            dThrower['verified'] = False

        # Create an instance
        try:
            oThrower = Thrower(dThrower)
        except ValueError as e:
            return Services.Effect(error=(1001, e.args[0]))

        # Store the instance
        if not oThrower.create(changes={"creator": "signup"}):
            return Services.Effect(error=1100)

        Services.create(
            'communications', 'email', {
                "_internal_":
                Services.internalKey(),
                "text_body":
                "Alias: %s\nEmail: %s" %
                (data['alias'], ('email' in data and data['email'] or '')),
                "subject":
                "Axegains Signup",
                "to":
                "*****@*****.**",
            })

        # If there's an e-mail
        if 'email' in data:

            # Send en e-mail for verification
            dConf = Conf.get("domain")
            sURL = "%s://external.%s/verify/%s/%s" % (
                dConf['protocol'], dConf['primary'], oThrower['_id'],
                oThrower['verified'])
            oEffect = Services.create(
                'communications', 'email', {
                    "_internal_":
                    Services.internalKey(),
                    "html_body":
                    Templates.generate('email/verify.html', {"url": sURL},
                                       data['locale']),
                    "subject":
                    Templates.generate('email/verify_subject.txt', {},
                                       data['locale']),
                    "to":
                    data['email'],
                })
            if oEffect.errorExists():
                return oEffect

        # If we don't already have a session, create one
        if 'session' not in data:
            oSesh = Sesh.create()

        # Else, load the existing session
        else:
            oSesh = Sesh.start(data['session'])

        # Add the thrower ID to it
        oSesh['thrower'] = oThrower.record()
        oSesh.save()

        # Return the session token
        return Services.Effect({
            "session": oSesh.id(),
            "thrower": {
                "_id": oSesh['thrower']['_id'],
                "alias": oSesh['thrower']['alias'],
                "org": oSesh['thrower']['org']
            }
        })
Пример #16
0
__version__ = "1.0.0"
__maintainer__ = "Chris Nasr"
__email__ = "*****@*****.**"
__created__ = "2019-03-29"

# Python imports
import os, platform

# Framework imports
from RestOC import Conf, REST, Services, Sesh

# App imports
from apps.webpoll import WebPoll

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
    Conf.load_merge(sConfOverride)

# Init the Sesh module
Sesh.init(Conf.get(("redis", "session")))

# Create the REST config instance
oRestConf = REST.Config(Conf.get("rest"))

# Set verbose mode if requested
if 'AXE_VERBOSE' in os.environ and os.environ['AXE_VERBOSE'] == '1':
    Services.verbose()

# Register all necessary services
Пример #17
0
"""

__author__ = "Chris Nasr"
__copyright__ = "OuroborosCoding"
__version__ = "1.0.0"
__created__ = "2018-11-17"

# Python imports
import os, platform

# Pip imports
import bottle
from RestOC import Conf, REST, Services

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
	Conf.load_merge(sConfOverride)

# Create the REST config instance
oRestConf = REST.Config(Conf.get("rest"))

# Set verbose mode if requested
_bVerbose = False
if 'AXE_VERBOSE' in os.environ and os.environ['AXE_VERBOSE'] == '1':
	_bVerbose = True

# Register the Services that will be accessible
Services.register({
	"auth": None,
Пример #18
0
# Pip imports
from RestOC import Conf, Record_Base, Record_ReDB, REST, Services

# Upgrade imports
from . import UpgradeLog, run

# If the version argument is missing
if len(sys.argv) < 2:
	print('Must specify the version to run:\n\tpython -m upgrades v1.0')
	sys.exit(1)

# Store the version
sVer = sys.argv[1].replace('.', '_')

# Load the config
Conf.load('../config.json')
sConfOverride = '../config.%s.json' % platform.node()
if os.path.isfile(sConfOverride):
	Conf.load_merge(sConfOverride)

# Add the global prepend and primary host to rethinkdb
Record_Base.dbPrepend(Conf.get(("rethinkdb", "prepend"), ''))
Record_ReDB.addHost('primary', Conf.get(("rethinkdb", "hosts", "primary")))

# Register all services
Services.register(
	{k:None for k in Conf.get(('rest', 'services'))},
	REST.Config(Conf.get("rest")),
	Conf.get(('services', 'salt'))
)
Пример #19
0
import os, platform, time

# Framework imports
from RestOC import Conf, Record_MySQL

# Records
from records import Company, User

# Services
from services.primary import Primary

# Only run if called directly
if __name__ == "__main__":

    # Load the config
    Conf.load('config.json')
    sConfOverride = 'config.%s.json' % platform.node()
    if os.path.isfile(sConfOverride):
        Conf.load_merge(sConfOverride)

    # Add hosts
    Record_MySQL.addHost('primary', Conf.get(("mysql", "hosts", "primary")))

    # Add the DB
    Record_MySQL.dbCreate(
        Conf.get(("mysql", "primary", "db"), "tims-ouroboros"), 'primary')

    # Install
    Primary.install()

    # Install admin user