From 9666a28dbfe06e822fe0d21b498f191d088ca3be Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 19:31:05 +0100 Subject: [PATCH 01/15] Fixing pipeline integration --- .devops/pipelines/azure-devops/build-main.yml | 116 ++++++++++-------- 1 file changed, 68 insertions(+), 48 deletions(-) diff --git a/.devops/pipelines/azure-devops/build-main.yml b/.devops/pipelines/azure-devops/build-main.yml index 7ee9c93..20eb405 100644 --- a/.devops/pipelines/azure-devops/build-main.yml +++ b/.devops/pipelines/azure-devops/build-main.yml @@ -10,58 +10,78 @@ trigger: - develop paths: include: - - /src/mavapa + - /mavapa + - /requirements.txt + +pool: + name: 'Azure Pipelines' + vmimage: 'ubuntu-latest' variables: - vmImageName: 'ubuntu-latest' - buildConfiguration: 'Release' - + project.id: 'mavapa' + artifact.docker.repo: 'sergiotocalini@dockerhub' + artifact.docker.name: 'mavapa' + artifact.helm.repo: '' + artifact.helm.name: 'mavapa' + artifact.helm.work: '$(Build.SourcesDirectory)/.devops/helm' + artifact.helm.dest: '$(Build.ArtifactStagingDirectory)/helm' + stages: - stage: 'Build' - condition: succeeded() - jobs: - - job: basics - displayName: 'Basics' - pool: - vmImage: $(vmImageName) - steps: - - task: GitVersion@5 - displayName: 'GitVersion' - inputs: - updateAssemblyInfo: true - preferBundledVersion: false - - script: echo %Action%%BuildVersion% - displayName: 'Set build version' - env: - Action: '##vso[build.updatebuildnumber]' - BuildVersion: $(GitVersion.SemVer) - - job: - displayName: 'Using' - dependsOn: basics - pool: - vmImage: $(vmImageName) - strategy: - matrix: - Python27: - python.version: '2.7' - Python37: - python.version: '3.7' - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - displayName: 'Use Python $(python.version)' - - script: | - sudo apt update - sudo apt install build-essential libsasl2-dev ldap-utils libldap2-dev libmysqlclient-dev python-pip python-virtualenv - displayName: 'Install OS dependencies' - - script: | - virtualenv -p python$(python.version) "~/.venvs/mavapa" - . "~/.venvs/mavapa/bin/activate" - pip install --upgrade pip - pip install pyflakes pylint nose nosexcover - pip install -r requirements.txt - displayName: 'Install Python dependencies' + steps: + - task: GitVersion@5 + displayName: 'GitVersion' + inputs: + configFilePath: GitVersion.yml + + - task: Docker@2 + displayName: 'docker: Build' + inputs: + containerRegistry: '$(artifact.docker.repo)' + repository: '$(artifact.docker.name)' + command: build + Dockerfile: .devops/docker/Dockerfile + buildContext: '$(Build.SourcesDirectory)' + tags: '$(Build.BuildNumber)' + arguments: '--build-arg "version=$(Build.BuildNumber)"' + + - task: Docker@2 + displayName: 'docker: Push' + inputs: + containerRegistry: '$(artifact.docker.repo)' + repository: '$(artifact.docker.name)' + command: push + tags: '$(Build.BuildNumber)' + condition: | + and + ( + succeeded(), + or + ( + not(in(variables['Build.Reason'], 'PullRequest')), + eq(variables['artifact.docker.publish'], true) + ) + ) + - task: AzureCLI@1 + displayName: "Helm: Package and Push" + inputs: + azureSubscription: '$(artifact.helm.sign)' + scriptLocation: inlineScript + inlineScript: | + az acr helm repo add -n $(artifact.helm.repo) + helm package $(artifact.helm.work) --app-version $(Build.BuildNumber) --version $(Build.BuildNumber) --destination $(artifact.helm.dest) + az acr helm push $(artifact.helm.dest)/$(artifact.helm.name)-$(Build.BuildNumber).tgz -n $(artifact.helm.repo) --force + condition: | + and + ( + succeeded(), + or + ( + not(in(variables['Build.Reason'], 'PullRequest')), + eq(variables['artifact.helm.publish'], true) + ) + ) + enabled: false From c6b6388c53404ac85f652953ceabd2702906e9f9 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 19:33:45 +0100 Subject: [PATCH 02/15] Adding gitversion configuration and removing stages --- .devops/pipelines/azure-devops/build-main.yml | 4 +- GitVersion.yml | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 GitVersion.yml diff --git a/.devops/pipelines/azure-devops/build-main.yml b/.devops/pipelines/azure-devops/build-main.yml index 20eb405..7654778 100644 --- a/.devops/pipelines/azure-devops/build-main.yml +++ b/.devops/pipelines/azure-devops/build-main.yml @@ -26,9 +26,7 @@ variables: artifact.helm.work: '$(Build.SourcesDirectory)/.devops/helm' artifact.helm.dest: '$(Build.ArtifactStagingDirectory)/helm' -stages: -- stage: 'Build' - steps: +steps: - task: GitVersion@5 displayName: 'GitVersion' inputs: diff --git a/GitVersion.yml b/GitVersion.yml new file mode 100644 index 0000000..22e96e6 --- /dev/null +++ b/GitVersion.yml @@ -0,0 +1,43 @@ +assembly-informational-format: '{NuGetVersion}' +next-version: 1.0.0 +mode: ContinuousDeployment +branches: + master: + mode: ContinuousDelivery + release: + tag: rc + hotfix: + tag: hf + increment: Patch + develop: + tag: dev + increment: Minor + feature: + tag: ft-{BranchName} + increment: Minor + devops: + regex: devops[/-] + tag: do-{BranchName} + source-branches: ['develop', 'feature'] + increment: Minor + temp: + regex: temp[/-] + tag: tmp-{BranchName} + source-branches: ['develop', 'feature'] + increment: Minor + test: + regex: tests?[/-] + tag: tst-{BranchName} + source-branches: ['develop', 'feature'] + increment: Minor + sec: + regex: sec[/-] + tag: sec-{BranchName} + source-branches: ['develop', 'feature'] + increment: Minor + bugfix: + regex: bugfix(es)?[/-] + tag: bug-{BranchName} + source-branches: ['develop', 'feature'] + increment: Minor + From ee0bb4f5fa37bd753db36af8de913d613979c0e5 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 19:41:15 +0100 Subject: [PATCH 03/15] Change the docker hub reference --- .devops/pipelines/azure-devops/build-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devops/pipelines/azure-devops/build-main.yml b/.devops/pipelines/azure-devops/build-main.yml index 7654778..9b44f2c 100644 --- a/.devops/pipelines/azure-devops/build-main.yml +++ b/.devops/pipelines/azure-devops/build-main.yml @@ -19,7 +19,7 @@ pool: variables: project.id: 'mavapa' - artifact.docker.repo: 'sergiotocalini@dockerhub' + artifact.docker.repo: '23a0ddbc-cb18-4dda-a06f-0bedcaa8e010' artifact.docker.name: 'mavapa' artifact.helm.repo: '' artifact.helm.name: 'mavapa' From 9cb08db7cfcde269f269c98f0ae84c682b339ef6 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 19:45:15 +0100 Subject: [PATCH 04/15] Fixing auth references --- .devops/pipelines/azure-devops/build-main.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.devops/pipelines/azure-devops/build-main.yml b/.devops/pipelines/azure-devops/build-main.yml index 9b44f2c..fd1e409 100644 --- a/.devops/pipelines/azure-devops/build-main.yml +++ b/.devops/pipelines/azure-devops/build-main.yml @@ -19,8 +19,8 @@ pool: variables: project.id: 'mavapa' - artifact.docker.repo: '23a0ddbc-cb18-4dda-a06f-0bedcaa8e010' - artifact.docker.name: 'mavapa' + artifact.docker.conn: '23a0ddbc-cb18-4dda-a06f-0bedcaa8e010' + artifact.docker.repo: 'sergiotocalini/mavapa' artifact.helm.repo: '' artifact.helm.name: 'mavapa' artifact.helm.work: '$(Build.SourcesDirectory)/.devops/helm' @@ -35,8 +35,8 @@ steps: - task: Docker@2 displayName: 'docker: Build' inputs: - containerRegistry: '$(artifact.docker.repo)' - repository: '$(artifact.docker.name)' + containerRegistry: '$(artifact.docker.conn)' + repository: '$(artifact.docker.repo)' command: build Dockerfile: .devops/docker/Dockerfile buildContext: '$(Build.SourcesDirectory)' @@ -46,8 +46,8 @@ steps: - task: Docker@2 displayName: 'docker: Push' inputs: - containerRegistry: '$(artifact.docker.repo)' - repository: '$(artifact.docker.name)' + containerRegistry: '$(artifact.docker.conn)' + repository: '$(artifact.docker.repo)' command: push tags: '$(Build.BuildNumber)' condition: | From b18ef0b2ed9c18e699a9c4d85c4315cb12bbf1c8 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 19:58:18 +0100 Subject: [PATCH 05/15] Change base image --- .devops/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index c1d3173..adad092 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -1,6 +1,6 @@ ARG version=master -FROM python:3-slim-buster +FROM python:3.9-slim-buster ARG version WORKDIR /app ENV PORT=5000 From 2a96bfb778e5f06d4e58aed199a1239cb523d32f Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 20:13:29 +0100 Subject: [PATCH 06/15] List dir --- .devops/docker/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index adad092..e26c78d 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -14,7 +14,8 @@ COPY ./.devops/docker/docker-entrypoint.sh / COPY ./.devops/docker/docker-entrypoint.d/* /docker-entrypoint.d/ COPY ./requirements.txt /app RUN echo "${version}" > VERSION \ - && pip install -r requirements.txt + && pip install -r requirements.txt \ + && ls -la /app COPY ./mavapa /app ENTRYPOINT ["/docker-entrypoint.sh"] CMD [ "gunicorn", "manage:run", "--workers=2", "--threads=4", "--worker-class=gthread", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "--access-logfile=-", "--error-logfile=-" ] From 1f4c56720c01fc69fc6b0cd34219109c2f48a475 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 20:19:59 +0100 Subject: [PATCH 07/15] Change the list dir --- .devops/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index e26c78d..0045403 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -15,7 +15,7 @@ COPY ./.devops/docker/docker-entrypoint.d/* /docker-entrypoint.d/ COPY ./requirements.txt /app RUN echo "${version}" > VERSION \ && pip install -r requirements.txt \ - && ls -la /app COPY ./mavapa /app +RUN ls -laR ENTRYPOINT ["/docker-entrypoint.sh"] CMD [ "gunicorn", "manage:run", "--workers=2", "--threads=4", "--worker-class=gthread", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "--access-logfile=-", "--error-logfile=-" ] From 1c4db8d50cb912725e289e6f763f9fdca8b482d6 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 21:03:20 +0100 Subject: [PATCH 08/15] Changing the base image --- .devops/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index 0045403..17080f5 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -1,6 +1,6 @@ ARG version=master -FROM python:3.9-slim-buster +FROM python:3-slim-buster ARG version WORKDIR /app ENV PORT=5000 From 0bc919f0233f150c9c7890d750aa534cd39b5d74 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 21:07:37 +0100 Subject: [PATCH 09/15] Updating COPY command --- .devops/docker/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index 17080f5..0af93fd 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -12,10 +12,10 @@ RUN apt-get update && apt-get install -y \ ldap-utils COPY ./.devops/docker/docker-entrypoint.sh / COPY ./.devops/docker/docker-entrypoint.d/* /docker-entrypoint.d/ -COPY ./requirements.txt /app -RUN echo "${version}" > VERSION \ - && pip install -r requirements.txt \ -COPY ./mavapa /app +COPY ./requirements.txt /app/ +RUN pip install -r requirements.txt +COPY ./mavapa/* /app/ +RUN echo "${version}" > VERSION RUN ls -laR ENTRYPOINT ["/docker-entrypoint.sh"] CMD [ "gunicorn", "manage:run", "--workers=2", "--threads=4", "--worker-class=gthread", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "--access-logfile=-", "--error-logfile=-" ] From 4c1579213b40e0c35253cc009f2e84dd2db5c2b4 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 21:22:47 +0100 Subject: [PATCH 10/15] Changing copy cmd --- .devops/docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index 0af93fd..792f15e 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -12,9 +12,9 @@ RUN apt-get update && apt-get install -y \ ldap-utils COPY ./.devops/docker/docker-entrypoint.sh / COPY ./.devops/docker/docker-entrypoint.d/* /docker-entrypoint.d/ -COPY ./requirements.txt /app/ +COPY ./requirements.txt /app RUN pip install -r requirements.txt -COPY ./mavapa/* /app/ +COPY ./mavapa /app RUN echo "${version}" > VERSION RUN ls -laR ENTRYPOINT ["/docker-entrypoint.sh"] From b30971b461193551c4f6377aab4d29011d48326a Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 22:05:09 +0100 Subject: [PATCH 11/15] Changing structure --- .devops/docker/Dockerfile | 2 +- mavapa/models.py | 184 +++++++++++++++++++++++++++++++++++ mavapa/modules/__init__.py | 2 + mavapa/modules/backends.py | 175 +++++++++++++++++++++++++++++++++ mavapa/{manage.py => run.py} | 4 +- mavapa/views.py | 8 +- 6 files changed, 368 insertions(+), 7 deletions(-) create mode 100644 mavapa/models.py create mode 100644 mavapa/modules/__init__.py create mode 100644 mavapa/modules/backends.py rename mavapa/{manage.py => run.py} (84%) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index 792f15e..b48b23e 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -18,4 +18,4 @@ COPY ./mavapa /app RUN echo "${version}" > VERSION RUN ls -laR ENTRYPOINT ["/docker-entrypoint.sh"] -CMD [ "gunicorn", "manage:run", "--workers=2", "--threads=4", "--worker-class=gthread", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "--access-logfile=-", "--error-logfile=-" ] +CMD [ "gunicorn", "run:main", "--workers=2", "--threads=4", "--worker-class=gthread", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "--access-logfile=-", "--error-logfile=-" ] diff --git a/mavapa/models.py b/mavapa/models.py new file mode 100644 index 0000000..3e541da --- /dev/null +++ b/mavapa/models.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from datetime import datetime, timedelta +from hashlib import md5 +from decimal import Decimal +from pony.orm import Database, Required, Optional, PrimaryKey, Set +from pony.orm import unicode, db_session, get +import string +import random + + +db = Database() + + +def make_hash(lenght=24): + s = string.ascii_letters + string.digits + r = ''.join([random.choice(s) for x in range(lenght)]) + return r + + +class Token(db.Entity): + _table_ = "tokens" + created_on = Required( + datetime, + sql_type='TIMESTAMP', default=datetime.now + ) + expired_on = Required( + datetime, + default=lambda: datetime.now() + timedelta(days=30) + ) + code = Required(unicode) + access_token = Optional(unicode) + status = Required(bool, default=True) + user = Required("User") + app = Required("App") + scopes = Set("Scope") + session = Required('Session') + + +class User(db.Entity): + _table_ = "users" + id = PrimaryKey(unicode, default=lambda: make_hash()) + email = Required(unicode, auto=True) + passwd = Optional(unicode, nullable=True) + firstname = Optional(unicode) + lastname = Optional(unicode) + dname = Optional( + unicode, default="{lastname}, {firstname}", column="displayname" + ) + mobile = Optional(unicode) + mailrecovery = Optional(unicode) + status = Required(bool, default=True) + admin = Required(bool, default=False) + created_at = Required(datetime, default=datetime.now) + last_seen = Optional(datetime, default=datetime.now) + genre = Optional(unicode, nullable=True, default=None) + lang = Required(unicode, default='Auto') + timezone = Optional(unicode, nullable=True) + tokens = Set(Token) + backend = Optional("Backend") + apps = Set("App") + retrieves = Set("Retrieve") + sessions = Set('Session') + + @property + @db_session + def displayname(self): + return self.dname.format(**self.to_dict()) + + @db_session + def avatar(self, size=256): + kwargs = {} + kwargs['size'] = size + kwargs['cdn'] = get(o for o in Config if o.key == 'CDN_AVATAR') + kwargs['photo'] = md5(self.email.encode('utf-8')).hexdigest() + if kwargs['cdn']: + return '{cdn}/{photo}?s={size}'.format(**kwargs) + else: + return '//s.gravatar.com/avatar/{photo}?s={size}'.format(**kwargs) + + +class Session(db.Entity): + _table_ = "sessions" + id = PrimaryKey(unicode, default=lambda: make_hash()) + created_on = Required( + datetime, sql_type='TIMESTAMP', default=datetime.now + ) + expired_on = Required( + datetime, default=lambda: datetime.now() + timedelta(days=30) + ) + agent_address = Required(unicode) + agent_string = Optional(unicode) + agent_platform = Optional(unicode) + agent_browser = Optional(unicode) + agent_version = Optional(unicode) + status = Required(bool, default=True) + user = Required(User) + tokens = Set(Token) + + +class App(db.Entity): + _table_ = "apps" + name = Required(unicode, unique=True) + desc = Optional(unicode, nullable=True) + url = Required(unicode) + icon = Required(unicode) + hidden = Required(bool, default=True) + client_id = Required(unicode) + client_secret = Required(unicode) + redirect_uri = Required(unicode) + created_at = Required( + datetime, sql_type='TIMESTAMP', default=datetime.now + ) + tags = Optional(unicode) + users = Set(User) + tokens = Set(Token) + scopes = Set("Scope") + notify_profiles = Set('NotifyProfile') + + +class Backend(db.Entity): + _table_ = "backends" + name = Required(unicode, unique=True, nullable=True) + desc = Optional(unicode) + type = Required(unicode, default='LOCAL') + host = Optional(unicode) + port = Optional(int) + binddn = Optional(unicode) + bindpw = Optional(unicode) + basedn = Optional(unicode) + filter = Optional(unicode) + timeout = Optional(int) + onfly = Required(bool, default=False) + login = Required(unicode, default='mail') + users = Set(User) + + +class Scope(db.Entity): + _table_ = "scopes" + permissions = Required(Decimal) + apps = Set(App) + tokens = Set(Token) + + +class Config(db.Entity): + _table_ = "configs" + key = Required(unicode, unique=True) + value = Required(unicode) + + +class Retrieve(db.Entity): + _table_ = "tokens_retrieves" + id = PrimaryKey(int, auto=True) + code = Required(unicode, unique=True, default=lambda: make_hash(8)) + created_on = Required( + datetime, sql_type='TIMESTAMP', default=datetime.now + ) + expired_on = Required( + datetime, default=lambda: datetime.now() + timedelta(hours=1) + ) + used_on = Optional(datetime, nullable=True) + methods = Optional(unicode, nullable=True, default='') + user = Required(User) + + +class NotifyAgent(db.Entity): + _table_ = 'notify_agents' + id = PrimaryKey(unicode, default=lambda: make_hash()) + name = Required(unicode) + type = Required(unicode) + host = Required(unicode) + key = Required(unicode) + last_seen = Required(datetime, sql_type='TIMESTAMP', default=datetime.now) + notify_profiles = Set('NotifyProfile') + + +class NotifyProfile(db.Entity): + _table_ = 'notify_profiles' + id = PrimaryKey(unicode, default=lambda: make_hash()) + name = Required(unicode) + type = Required(unicode) + policy = Required(unicode) + notify_agents = Set(NotifyAgent) + apps = Set(App) diff --git a/mavapa/modules/__init__.py b/mavapa/modules/__init__.py new file mode 100644 index 0000000..cf89f88 --- /dev/null +++ b/mavapa/modules/__init__.py @@ -0,0 +1,2 @@ +#!/usr/bin/env python +from .backends import * diff --git a/mavapa/modules/backends.py b/mavapa/modules/backends.py new file mode 100644 index 0000000..0166fe2 --- /dev/null +++ b/mavapa/modules/backends.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +import os +import hashlib +import ldap +from codecs import encode +from base64 import b64encode +from anytree import Node +from anytree.exporter import DictExporter + + +class LDAP(): + def __init__(self, **kwargs): + # Loading defaults connection options + kwargs.setdefault('host', 'localhost') + kwargs.setdefault('port', 389) + kwargs.setdefault('binddn', '') + kwargs.setdefault('bindpw', '') + kwargs.setdefault('bytes_mode', False) + self.copt = kwargs.copy() + # Connect with the defaults options + self.connect() + + def connect(self, **kwargs): + self.copt.update(kwargs) + try: + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) + self.cstr = ldap.initialize( + self.copt['host'], + bytes_mode=self.copt['bytes_mode'] + ) + self.cstr.set_option( + ldap.OPT_X_TLS_REQUIRE_CERT, + ldap.OPT_X_TLS_NEVER + ) + self.cstr.set_option(ldap.OPT_REFERRALS, 0) + self.cstr.set_option(ldap.OPT_PROTOCOL_VERSION, 3) + self.cstr.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND) + self.cstr.set_option(ldap.OPT_X_TLS_DEMAND, True) + self.cstr.set_option(ldap.OPT_DEBUG_LEVEL, 255) + if all(map(lambda x: self.copt[x] != '', ['binddn', 'bindpw'])): + self.cstr.simple_bind_s( + self.copt['binddn'], self.copt['bindpw'] + ) + except ldap.INVALID_CREDENTIALS: + print(ldap.INVALID_CREDENTIALS) + except ldap.SERVER_DOWN: + print(ldap.SERVER_DOWN) + except ldap.LDAPError: + print(ldap.LDAPError) + + def disconnect(self): + try: + self.cstr.unbind() + except ldap.LDAPError as e: + print(e) + + def auth(self, username, password): + try: + conn = ldap.initialize(self.copt['host']) + conn.set_option(ldap.OPT_REFERRALS, 0) + conn.simple_bind_s(username, password) + return True + except ldap.LDAPError: + conn.unbind_s() + return False + + def tree(self, **kwargs): + kwargs.setdefault('filter', '(objectClass=*)') + kwargs.setdefault('limit', -1) + query = self.query(**kwargs) + exporter = DictExporter() + root = Node(kwargs['basedn'], dn=kwargs['basedn']) + if query: + res = [] + for x in query: + if not kwargs['basedn'] == x[0]: + entries = ( + x[0].replace(',%s' % (kwargs['basedn']), '') + ).split(',') + entries.reverse() + res.append(','.join(entries)) + res.sort() + for dn in res: + entries = dn.split(',') + parent = root + for e in entries: + node = None + for c in parent.children: + if c.name == e: + node = c + if not node: + node = Node( + e, parent=parent, dn=','.join([e, parent.dn]) + ) + parent = node + return exporter.export(root) + + def query(self, **kwargs): + codec = 'utf-8' + kwargs.setdefault('basedn', u'') + kwargs.setdefault('filter', '(objectclass=person)') + kwargs.setdefault('attrs', ['*']) + kwargs.setdefault('scope', ldap.SCOPE_SUBTREE) + kwargs.setdefault('limit', 25) + kwargs.setdefault('exclude', []) + kwargs.setdefault('dn', False) + try: + rows = [] + if not kwargs['dn']: + kwargs['attrs'] = [ + encode(a).decode(codec) for a in kwargs['attrs'] + ] + data = self.cstr.search( + encode(kwargs['basedn']).decode(codec), kwargs['scope'], + encode(kwargs['filter']).decode(codec), kwargs['attrs'] + ) + res = [] + while 1: + rtype, rdata = self.cstr.result(data, 0) + if (rdata == []): + break + else: + if rtype == ldap.RES_SEARCH_ENTRY: + for i in rdata: + res.append(i) + else: + res = self.cstr.search_s(kwargs['filter'], kwargs['scope']) + + for idx in res: + entry = {} + for attr in idx[1]: + if attr not in kwargs['exclude']: + entry[attr] = [] + for a in idx[1][attr]: + try: + e = a.decode(codec) + except Exception: + e = b64encode(a).decode(codec) + entry[attr].append(e) + rows.append((idx[0], entry)) + except ldap.LDAPError: + print(ldap.LDAPError) + except Exception as e: + print(str(e)) + return rows + + def modify(self, dn, dict_new, dict_old={}): + codec = 'utf-8' + tasks = [] + for i in dict_new: + attr_new = [encode(dict_new[i], codec)] + if i in dict_old: + if dict_old[i] == '*': + tasks.append((ldap.MOD_REPLACE, i, attr_new)) + else: + attr_old = [encode(dict_old[i], codec)] + tasks.append((ldap.MOD_DELETE, i, attr_old)) + tasks.append((ldap.MOD_ADD, i, attr_new)) + else: + tasks.append((ldap.MOD_ADD, i, dict_new[i])) + + print(dn, tasks) + self.cstr.modify_s(dn, tasks) + + def make_secret(self, passwd, enc='SSHA'): + salt = os.urandom(4) + sha = hashlib.sha1(passwd) + sha.update(salt) + + digest_salt_b64 = '{0}{1}'.format( + sha.digest(), salt + ).encode('base64').strip() + tagged_digest_salt = '{{{0}}}{1}'.format(enc, digest_salt_b64) + + return tagged_digest_salt diff --git a/mavapa/manage.py b/mavapa/run.py similarity index 84% rename from mavapa/manage.py rename to mavapa/run.py index 72ef6ff..4f05494 100644 --- a/mavapa/manage.py +++ b/mavapa/run.py @@ -13,8 +13,8 @@ def simple(env, resp): addr = app.config.get('BIND', '0.0.0.0') port = app.config.get('PORT', 7001) root = app.config.get('APPLICATION_ROOT', '/') -run = DispatcherMiddleware(simple, {root: app}) +main = DispatcherMiddleware(simple, {root: app}) if __name__ == "__main__": - run_simple(addr, port, run) + run_simple(addr, port, main) diff --git a/mavapa/views.py b/mavapa/views.py index 73bb0eb..e5faed9 100644 --- a/mavapa/views.py +++ b/mavapa/views.py @@ -13,10 +13,10 @@ from pony.orm import select, count, commit, desc from forms import Login, Reset # from .lib import * -from lib.models import db, db_session -from lib.models import App, Token, User, Backend, Session, Retrieve -from lib.models import NotifyAgent -from lib.backends import LDAP +from models import db, db_session +from models import App, Token, User, Backend, Session, Retrieve +from models import NotifyAgent +from modules.backends import LDAP from mavapa_server import mavapa_server from datetime import datetime, timedelta From d4640dd561632d8bdbdfa44e2e7699d015264b90 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 22:12:49 +0100 Subject: [PATCH 12/15] Fixing lib import --- .devops/docker/Dockerfile | 5 ++--- mavapa/mavapa_server.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.devops/docker/Dockerfile b/.devops/docker/Dockerfile index b48b23e..6c161de 100644 --- a/.devops/docker/Dockerfile +++ b/.devops/docker/Dockerfile @@ -9,13 +9,12 @@ RUN apt-get update && apt-get install -y \ build-essential \ libldap2-dev \ libsasl2-dev \ - ldap-utils + ldap-utils \ + && echo "${version}" > VERSION COPY ./.devops/docker/docker-entrypoint.sh / COPY ./.devops/docker/docker-entrypoint.d/* /docker-entrypoint.d/ COPY ./requirements.txt /app RUN pip install -r requirements.txt COPY ./mavapa /app -RUN echo "${version}" > VERSION -RUN ls -laR ENTRYPOINT ["/docker-entrypoint.sh"] CMD [ "gunicorn", "run:main", "--workers=2", "--threads=4", "--worker-class=gthread", "--worker-tmp-dir", "/dev/shm", "-b", "0.0.0.0:5000", "--access-logfile=-", "--error-logfile=-" ] diff --git a/mavapa/mavapa_server.py b/mavapa/mavapa_server.py index 367e8a2..f70a7b2 100644 --- a/mavapa/mavapa_server.py +++ b/mavapa/mavapa_server.py @@ -8,7 +8,7 @@ from flask import Blueprint, render_template, abort from flask import redirect, request, jsonify, session, url_for from pony.orm import commit -from lib import * +from modules import * from forms import * MAVAPA_URL = '' From e4ec827b3baff8fabf19b7b1d22b651471087fd8 Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 22:18:31 +0100 Subject: [PATCH 13/15] Removing unused modules --- mavapa/mavapa_server.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mavapa/mavapa_server.py b/mavapa/mavapa_server.py index f70a7b2..965dc97 100644 --- a/mavapa/mavapa_server.py +++ b/mavapa/mavapa_server.py @@ -8,8 +8,7 @@ from flask import Blueprint, render_template, abort from flask import redirect, request, jsonify, session, url_for from pony.orm import commit -from modules import * -from forms import * +from models import db_session MAVAPA_URL = '' AUTH_URL = MAVAPA_URL + '/auth?response_type=code' From b9f183a457fc55742ee0cc7db695b162d88d880b Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 22:34:36 +0100 Subject: [PATCH 14/15] Removing module folder --- mavapa/{modules => }/backends.py | 0 mavapa/mavapa_server.py | 13 ++++++++----- mavapa/modules/__init__.py | 2 -- mavapa/run.py | 3 +-- mavapa/views.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename mavapa/{modules => }/backends.py (100%) delete mode 100644 mavapa/modules/__init__.py diff --git a/mavapa/modules/backends.py b/mavapa/backends.py similarity index 100% rename from mavapa/modules/backends.py rename to mavapa/backends.py diff --git a/mavapa/mavapa_server.py b/mavapa/mavapa_server.py index 965dc97..823959f 100644 --- a/mavapa/mavapa_server.py +++ b/mavapa/mavapa_server.py @@ -8,7 +8,7 @@ from flask import Blueprint, render_template, abort from flask import redirect, request, jsonify, session, url_for from pony.orm import commit -from models import db_session +from models import db_session, select, Token MAVAPA_URL = '' AUTH_URL = MAVAPA_URL + '/auth?response_type=code' @@ -33,7 +33,7 @@ def get_data(table, **kwargs): else: return select(o for o in eval(table)) - + @db_session def save_code(app, user, code): """ @@ -75,7 +75,7 @@ def who_im(): @mavapa_server.route('/token', methods=['POST']) @db_session def token(): - grant_type = request.form.get('grant_type') + # grant_type = request.form.get('grant_type') code = request.form.get('code') redirect_uri = request.form.get('redirect_uri') redirect_uri = urllib.parse.unquote(redirect_uri) @@ -115,7 +115,11 @@ def accept_app(): session.pop('redirect_uri') if accepted: account = get_data('User', email=user) - app = get_data('App', client_id=client_id, redirect_uri=redirect_uri) + app = get_data( + 'App', + client_id=client_id, + redirect_uri=redirect_uri + ) account.apps.add(app) commit() return redirect(auth_url) @@ -160,4 +164,3 @@ def auth(): 'scopes': scopes, } return jsonify(data) - diff --git a/mavapa/modules/__init__.py b/mavapa/modules/__init__.py deleted file mode 100644 index cf89f88..0000000 --- a/mavapa/modules/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env python -from .backends import * diff --git a/mavapa/run.py b/mavapa/run.py index 4f05494..f399031 100644 --- a/mavapa/run.py +++ b/mavapa/run.py @@ -2,7 +2,6 @@ from werkzeug.serving import run_simple from werkzeug.middleware.dispatcher import DispatcherMiddleware from views import app -from forms import Login def simple(env, resp): @@ -13,7 +12,7 @@ def simple(env, resp): addr = app.config.get('BIND', '0.0.0.0') port = app.config.get('PORT', 7001) root = app.config.get('APPLICATION_ROOT', '/') -main = DispatcherMiddleware(simple, {root: app}) +main = DispatcherMiddleware(simple, {root: app}) if __name__ == "__main__": diff --git a/mavapa/views.py b/mavapa/views.py index e5faed9..fb4ca39 100644 --- a/mavapa/views.py +++ b/mavapa/views.py @@ -16,7 +16,7 @@ from models import db, db_session from models import App, Token, User, Backend, Session, Retrieve from models import NotifyAgent -from modules.backends import LDAP +from backends import LDAP from mavapa_server import mavapa_server from datetime import datetime, timedelta From e3249431996b22d8fbe87d1132193cc6c5ae9ada Mon Sep 17 00:00:00 2001 From: Sergio Tocalini Joerg Date: Tue, 2 Feb 2021 22:49:45 +0100 Subject: [PATCH 15/15] Fixing import issue --- mavapa/mavapa_server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mavapa/mavapa_server.py b/mavapa/mavapa_server.py index 823959f..c006245 100644 --- a/mavapa/mavapa_server.py +++ b/mavapa/mavapa_server.py @@ -7,8 +7,8 @@ from datetime import datetime, timedelta from flask import Blueprint, render_template, abort from flask import redirect, request, jsonify, session, url_for -from pony.orm import commit -from models import db_session, select, Token +from pony.orm import select, commit +from models import db_session, Token MAVAPA_URL = '' AUTH_URL = MAVAPA_URL + '/auth?response_type=code'