Browse Source

Merge branch 'master' into partials-update

Conflicts:
	realms/modules/wiki/views.py
master
Chase Sterling 7 years ago
parent
commit
7260c88571
42 changed files with 202 additions and 78 deletions
  1. +2
    -1
      bower.json
  2. +13
    -10
      realms/__init__.py
  3. +12
    -6
      realms/commands.py
  4. +6
    -2
      realms/config/__init__.py
  5. +2
    -0
      realms/lib/__init__.py
  6. +4
    -1
      realms/lib/hook.py
  7. +5
    -1
      realms/lib/model.py
  8. +5
    -1
      realms/lib/test.py
  9. +4
    -1
      realms/lib/util.py
  10. +1
    -0
      realms/modules/__init__.py
  11. +4
    -1
      realms/modules/auth/__init__.py
  12. +3
    -1
      realms/modules/auth/ldap/__init__.py
  13. +3
    -1
      realms/modules/auth/ldap/forms.py
  14. +5
    -2
      realms/modules/auth/ldap/models.py
  15. +7
    -3
      realms/modules/auth/ldap/views.py
  16. +3
    -1
      realms/modules/auth/local/__init__.py
  17. +5
    -2
      realms/modules/auth/local/commands.py
  18. +2
    -0
      realms/modules/auth/local/forms.py
  19. +3
    -0
      realms/modules/auth/local/hooks.py
  20. +7
    -3
      realms/modules/auth/local/models.py
  21. +8
    -4
      realms/modules/auth/local/views.py
  22. +8
    -4
      realms/modules/auth/models.py
  23. +3
    -1
      realms/modules/auth/oauth/__init__.py
  24. +3
    -1
      realms/modules/auth/oauth/models.py
  25. +3
    -1
      realms/modules/auth/oauth/views.py
  26. +1
    -0
      realms/modules/auth/tests.py
  27. +8
    -2
      realms/modules/auth/views.py
  28. +1
    -0
      realms/modules/search/__init__.py
  29. +3
    -0
      realms/modules/search/commands.py
  30. +3
    -1
      realms/modules/search/hooks.py
  31. +3
    -0
      realms/modules/search/models.py
  32. +5
    -1
      realms/modules/search/views.py
  33. +4
    -1
      realms/modules/wiki/__init__.py
  34. +2
    -0
      realms/modules/wiki/assets.py
  35. +3
    -0
      realms/modules/wiki/hooks.py
  36. +5
    -1
      realms/modules/wiki/models.py
  37. +4
    -0
      realms/modules/wiki/tests.py
  38. +5
    -0
      realms/modules/wiki/views.py
  39. +28
    -21
      realms/static/js/mdr.js
  40. +1
    -1
      realms/templates/layout.html
  41. +2
    -0
      realms/version.py
  42. +3
    -2
      setup.py

+ 2
- 1
bower.json View File

@@ -10,7 +10,8 @@
"keymaster": "madrobby/keymaster",
"ace-builds": "~1.2.3",
"parsleyjs": "~2.3.10",
"marked": "~0.3.2",
"markdown-it": "~7.0.0",
"markdown-it-anchor": "https://wzrd.in/standalone/markdown-it-anchor@2.5.0",
"js-yaml": "~3.6.0",
"store-js": "~1.3.16",
"bootswatch-dist": "3.3.6-flatly",


+ 13
- 10
realms/__init__.py View File

@@ -1,16 +1,19 @@
import functools
import sys
from __future__ import absolute_import

import sys
# Set default encoding to UTF-8
reload(sys)
# noinspection PyUnresolvedReferences
sys.setdefaultencoding('utf-8')

import functools
import base64
import time
import json
import httplib
import traceback
import six.moves.http_client as httplib
from functools import update_wrapper

import click
from flask import Flask, request, render_template, url_for, redirect, g
from flask_cache import Cache
@@ -18,16 +21,15 @@ from flask_login import LoginManager, current_user
from flask_sqlalchemy import SQLAlchemy
from flask_assets import Environment, Bundle
from flask_ldap_login import LDAPLoginManager
from functools import update_wrapper
from werkzeug.routing import BaseConverter
from werkzeug.exceptions import HTTPException
from sqlalchemy.ext.declarative import declarative_base

from .modules.search.models import Search
from .lib.util import to_canonical, remove_ext, mkdir_safe, gravatar_url, to_dict
from .lib.hook import HookModelMeta, HookMixin
from .lib.util import is_su, in_virtualenv
from .version import __version__
from realms.modules.search.models import Search
from realms.lib.util import to_canonical, remove_ext, mkdir_safe, gravatar_url, to_dict
from realms.lib.hook import HookModelMeta, HookMixin
from realms.lib.util import is_su, in_virtualenv
from realms.version import __version__


class Application(Flask):
@@ -229,7 +231,8 @@ assets.register('main.js',
'vendor/components-bootstrap/js/bootstrap.js',
'vendor/handlebars/handlebars.js',
'vendor/js-yaml/dist/js-yaml.js',
'vendor/marked/lib/marked.js',
'vendor/markdown-it/dist/markdown-it.js',
'vendor/markdown-it-anchor/index.0',
'js/html-sanitizer-minified.js', # don't minify?
'vendor/highlightjs/highlight.pack.js',
'vendor/parsleyjs/dist/parsley.js',


+ 12
- 6
realms/commands.py View File

@@ -1,17 +1,23 @@
from realms import config, create_app, db, __version__, cli, cache
from realms.lib.util import random_string, in_virtualenv, green, yellow, red
from subprocess import call, Popen
from multiprocessing import cpu_count
import click
from __future__ import absolute_import

import json
import sys
import os
import pip
import time
import subprocess
from subprocess import call, Popen
from multiprocessing import cpu_count

import click
import pip

from realms import config, create_app, db, __version__, cli, cache
from realms.lib.util import random_string, in_virtualenv, green, yellow, red


config = config.conf


# called to discover commands in modules
app = create_app()



+ 6
- 2
realms/config/__init__.py View File

@@ -1,7 +1,11 @@
from __future__ import absolute_import

import json
import os
import sys
from urlparse import urlparse

# noinspection PyUnresolvedReferences
from six.moves.urllib.parse import urlparse

from realms.lib.util import in_vagrant

@@ -71,7 +75,7 @@ class Config(object):

CACHE_MEMCACHED_SERVERS = ['127.0.0.1:11211']

# Valid options: simple, elasticsearch, woosh
# Valid options: simple, elasticsearch, whoosh
SEARCH_TYPE = 'simple'

ELASTICSEARCH_URL = 'http://127.0.0.1:9200'


+ 2
- 0
realms/lib/__init__.py View File

@@ -0,0 +1,2 @@
from __future__ import absolute_import


+ 4
- 1
realms/lib/hook.py View File

@@ -1,7 +1,10 @@
from flask_sqlalchemy import DeclarativeMeta
from __future__ import absolute_import

from functools import wraps

from flask_sqlalchemy import DeclarativeMeta



def hook_func(name, fn):
@wraps(fn)


+ 5
- 1
realms/lib/model.py View File

@@ -1,6 +1,10 @@
from __future__ import absolute_import

import json
from sqlalchemy import not_, and_
from datetime import datetime

from sqlalchemy import not_, and_

from realms import db




+ 5
- 1
realms/lib/test.py View File

@@ -1,9 +1,13 @@
from __future__ import absolute_import

import os
import shutil
import tempfile

from flask_testing import TestCase
from realms.lib.util import random_string
from realms import create_app
from realms.lib.util import random_string


class BaseTest(TestCase):


+ 4
- 1
realms/lib/util.py View File

@@ -1,4 +1,5 @@
import click
from __future__ import absolute_import

import re
import os
import hashlib
@@ -6,6 +7,8 @@ import json
import string
import random
import sys

import click
from jinja2 import Template




+ 1
- 0
realms/modules/__init__.py View File

@@ -0,0 +1 @@
from __future__ import absolute_import

+ 4
- 1
realms/modules/auth/__init__.py View File

@@ -1,7 +1,10 @@
from realms import login_manager
from __future__ import absolute_import

from flask import request, flash, redirect
from flask_login import login_url

from realms import login_manager

modules = set()

@login_manager.unauthorized_handler


+ 3
- 1
realms/modules/auth/ldap/__init__.py View File

@@ -1,3 +1,5 @@
from ..models import Auth
from __future__ import absolute_import

from realms.modules.auth.models import Auth

Auth.register('ldap')

+ 3
- 1
realms/modules/auth/ldap/forms.py View File

@@ -1,7 +1,9 @@
from __future__ import absolute_import

from flask_wtf import Form
from wtforms import StringField, PasswordField, validators


class LoginForm(Form):
login = StringField('Username', [validators.DataRequired()])
password = PasswordField('Password', [validators.DataRequired()])
password = PasswordField('Password', [validators.DataRequired()])

+ 5
- 2
realms/modules/auth/ldap/models.py View File

@@ -1,8 +1,11 @@
from __future__ import absolute_import

from flask import render_template
from flask_login import login_user
from realms import ldap
from flask_ldap_login import LDAPLoginForm
from ..models import BaseUser

from realms import ldap
from realms.modules.auth.models import BaseUser


users = {}


+ 7
- 3
realms/modules/auth/ldap/views.py View File

@@ -1,7 +1,11 @@
from flask import current_app, request, redirect, Blueprint, flash, url_for
from ..ldap.models import User
from __future__ import absolute_import

from flask import current_app, request, redirect, Blueprint, flash, url_for, session
from flask_ldap_login import LDAPLoginForm

from .models import User


blueprint = Blueprint('auth.ldap', __name__)


@@ -14,6 +18,6 @@ def login():
return redirect(url_for('auth.login'))

if User.auth(form.user, request.form['password']):
return redirect(request.args.get("next") or url_for(current_app.config['ROOT_ENDPOINT']))
return redirect(session.get("next_url") or url_for(current_app.config['ROOT_ENDPOINT']))
else:
return redirect(url_for('auth.login'))

+ 3
- 1
realms/modules/auth/local/__init__.py View File

@@ -1,3 +1,5 @@
from ..models import Auth
from __future__ import absolute_import

from realms.modules.auth.models import Auth

Auth.register('local')

+ 5
- 2
realms/modules/auth/local/commands.py View File

@@ -1,8 +1,11 @@
from __future__ import absolute_import

import click

from realms import cli_group
from realms.lib.util import random_string
from realms.modules.auth.local.models import User
from realms.lib.util import green, red, yellow
from realms import cli_group
from .models import User


@cli_group(short_help="Auth Module")


+ 2
- 0
realms/modules/auth/local/forms.py View File

@@ -1,3 +1,5 @@
from __future__ import absolute_import

from flask_wtf import Form
from wtforms import StringField, PasswordField, validators



+ 3
- 0
realms/modules/auth/local/hooks.py View File

@@ -1,5 +1,8 @@
from __future__ import absolute_import

from flask import current_app
from flask_wtf import RecaptchaField

from .forms import RegistrationForm




+ 7
- 3
realms/modules/auth/local/models.py View File

@@ -1,11 +1,15 @@
from __future__ import absolute_import

from hashlib import sha256

from flask import current_app, render_template
from flask_login import logout_user, login_user
from itsdangerous import URLSafeSerializer, BadSignature

from realms import login_manager, db
from realms.lib.model import Model
from ..models import BaseUser
from realms.modules.auth.models import BaseUser
from .forms import LoginForm
from itsdangerous import URLSafeSerializer, BadSignature
from hashlib import sha256


@login_manager.token_loader


+ 8
- 4
realms/modules/auth/local/views.py View File

@@ -1,6 +1,10 @@
from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for
from realms.modules.auth.local.models import User
from realms.modules.auth.local.forms import LoginForm, RegistrationForm
from __future__ import absolute_import

from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for, session

from .models import User
from .forms import LoginForm, RegistrationForm


blueprint = Blueprint('auth.local', __name__)

@@ -46,6 +50,6 @@ def register():
User.create(request.form['username'], request.form['email'], request.form['password'])
User.auth(request.form['email'], request.form['password'])

return redirect(request.args.get("next") or url_for(current_app.config['ROOT_ENDPOINT']))
return redirect(session.get("next_url") or url_for(current_app.config['ROOT_ENDPOINT']))

return render_template("auth/register.html", form=form)

+ 8
- 4
realms/modules/auth/models.py View File

@@ -1,12 +1,16 @@
from __future__ import absolute_import

import importlib
from hashlib import sha256

from flask import current_app
from flask_login import UserMixin, logout_user, AnonymousUserMixin
from itsdangerous import URLSafeSerializer, BadSignature
import bcrypt

from realms import login_manager
from realms.lib.util import gravatar_url
from itsdangerous import URLSafeSerializer, BadSignature
from hashlib import sha256
from . import modules
import bcrypt
import importlib


@login_manager.user_loader


+ 3
- 1
realms/modules/auth/oauth/__init__.py View File

@@ -1,3 +1,5 @@
from ..models import Auth
from __future__ import absolute_import

from realms.modules.auth.models import Auth

Auth.register('oauth')

+ 3
- 1
realms/modules/auth/oauth/models.py View File

@@ -1,9 +1,11 @@
from __future__ import absolute_import

from flask import session
from flask_login import login_user
from flask_oauthlib.client import OAuth

from realms import config
from ..models import BaseUser
from realms.modules.auth.models import BaseUser

config = config.conf



+ 3
- 1
realms/modules/auth/oauth/views.py View File

@@ -1,3 +1,5 @@
from __future__ import absolute_import

from flask import Blueprint, url_for, request, flash, redirect, session, current_app
from .models import User

@@ -16,7 +18,7 @@ def login(provider):

@blueprint.route('/login/oauth/<provider>/callback')
def callback(provider):
next_url = request.args.get('next') or url_for(current_app.config['ROOT_ENDPOINT'])
next_url = session.get('next_url') or url_for(current_app.config['ROOT_ENDPOINT'])
try:
remote_app = User.get_app(provider)
resp = remote_app.authorized_response()


+ 1
- 0
realms/modules/auth/tests.py View File

@@ -0,0 +1 @@
from __future__ import absolute_import

+ 8
- 2
realms/modules/auth/views.py View File

@@ -1,12 +1,18 @@
from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for
from __future__ import absolute_import

from flask import current_app, render_template, request, redirect, Blueprint, flash, url_for, session
from flask_login import logout_user
from realms.modules.auth.models import Auth

from .models import Auth


blueprint = Blueprint('auth', __name__, template_folder='templates')


@blueprint.route("/login", methods=['GET', 'POST'])
def login():
next_url = request.args.get('next') or url_for(current_app.config['ROOT_ENDPOINT'])
session['next_url'] = next_url
return render_template("auth/login.html", forms=Auth.login_forms())




+ 1
- 0
realms/modules/search/__init__.py View File

@@ -0,0 +1 @@
from __future__ import absolute_import

+ 3
- 0
realms/modules/search/commands.py View File

@@ -1,5 +1,8 @@
from __future__ import absolute_import

import click
from flask import current_app

from realms import search, cli_group
from realms.modules.wiki.models import Wiki



+ 3
- 1
realms/modules/search/hooks.py View File

@@ -1,5 +1,7 @@
from realms.modules.wiki.models import WikiPage
from __future__ import absolute_import

from realms import search
from realms.modules.wiki.models import WikiPage


@WikiPage.after('write')


+ 3
- 0
realms/modules/search/models.py View File

@@ -1,7 +1,10 @@
from __future__ import absolute_import

import re
import sys

from flask import g, current_app

from realms.lib.util import filename_to_cname




+ 5
- 1
realms/modules/search/views.py View File

@@ -1,7 +1,11 @@
from __future__ import absolute_import

from flask import render_template, request, Blueprint, current_app
from flask.ext.login import current_user
from flask_login import current_user

from realms import search as search_engine


blueprint = Blueprint('search', __name__, template_folder='templates')




+ 4
- 1
realms/modules/wiki/__init__.py View File

@@ -1,6 +1,9 @@
from __future__ import absolute_import

import os
import sys
from realms.modules.wiki.models import Wiki

from .models import Wiki


def init(app):


+ 2
- 0
realms/modules/wiki/assets.py View File

@@ -1,3 +1,5 @@
from __future__ import absolute_import

from realms import assets

assets.register('editor.js',


+ 3
- 0
realms/modules/wiki/hooks.py View File

@@ -1,4 +1,7 @@
from __future__ import absolute_import

from flask import g, current_app

from .models import Wiki




+ 5
- 1
realms/modules/wiki/models.py View File

@@ -1,13 +1,17 @@
from __future__ import absolute_import

import os
import posixpath
import re

import ghdiff
import yaml
from dulwich.object_store import tree_lookup_path
from dulwich.repo import Repo, NotGitRepository
from realms.lib.util import cname_to_filename, filename_to_cname
from realms import cache
from realms.lib.hook import HookMixin
from realms.lib.util import cname_to_filename, filename_to_cname


class PageNotFound(Exception):


+ 4
- 0
realms/modules/wiki/tests.py View File

@@ -1,6 +1,10 @@
from __future__ import absolute_import

import json

from nose.tools import *
from flask import url_for

from realms.lib.util import cname_to_filename, filename_to_cname
from realms.lib.test import BaseTest



+ 5
- 0
realms/modules/wiki/views.py View File

@@ -1,12 +1,17 @@
from __future__ import absolute_import

import collections
import itertools
import sys
from datetime import datetime

from flask import abort, g, render_template, request, redirect, Blueprint, flash, url_for, current_app
from flask_login import login_required, current_user

from realms.lib.util import to_canonical, remove_ext, gravatar_url
from .models import PageNotFound


blueprint = Blueprint('wiki', __name__, template_folder='templates',
static_folder='static', static_url_path='/static/wiki')



+ 28
- 21
realms/static/js/mdr.js View File

@@ -38,15 +38,28 @@ var metaMarked = function(src, opt, callback) {
}
};

marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false
var markdownit = window.markdownit({
html: true,
linkify: true,
typographer: true,
highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return hljs.highlight(lang, str).value;
} catch (__) {
}
}

return ''; // use external default escaping
}
}).use(markdownItAnchor, {
level: 1,
// slugify: string => string,
permalink: false,
// renderPermalink: (slug, opts, state, permalink) => {},
permalinkClass: 'header-anchor',
permalinkSymbol: '¶',
permalinkBefore: false
});

// Markdown Renderer
@@ -54,9 +67,8 @@ var MDR = {
meta: null,
md: null,
sanitize: true, // Override
renderer: new marked.Renderer(),
parse: function(md){
return marked(md, { renderer: this.renderer });
return markdownit.render(md);
},
convert: function(md, partials, sanitize) {
if (this.sanitize !== null) {
@@ -117,13 +129,8 @@ var MDR = {
}
};

MDR.renderer.table = function(header, body) {
return '<table class="table table-bordered">\n'
+ '<thead>\n'
+ header
+ '</thead>\n'
+ '<tbody>\n'
+ body
+ '</tbody>\n'
+ '</table>\n';
};
// Add some custom classes to table tags
markdownit.renderer.rules.table_open = function (tokens, idx, options, env, self) {
tokens[idx].attrPush(['class', 'table table-bordered']);
return self.renderToken(tokens, idx, options);
};

+ 1
- 1
realms/templates/layout.html View File

@@ -72,7 +72,7 @@
</ul>
</li>
{% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="fa fa-user"></i> &nbsp;Login</a></li>
<li><a href="{{ url_for('auth.login', next=request.path) }}"><i class="fa fa-user"></i> &nbsp;Login</a></li>
{% if config.REGISTRATION_ENABLED and 'auth.local' in config.MODULES %}
<li><a href="{{ url_for('auth.local.register') }}"><i class="fa fa-users"></i> &nbsp;Register</a></li>
{% endif %}


+ 2
- 0
realms/version.py View File

@@ -1 +1,3 @@
from __future__ import absolute_import

__version__ = '0.8.1'

+ 3
- 2
setup.py View File

@@ -1,5 +1,5 @@
from setuptools import setup, find_packages
import os
from setuptools import setup, find_packages

if os.environ.get('USER', '') == 'vagrant':
del os.link
@@ -43,7 +43,8 @@ setup(name='realms-wiki',
'itsdangerous==0.24',
'markdown2==2.3.1',
'python-ldap==2.4.22',
'simplejson==3.6.3'
'simplejson==3.6.3',
'six==1.10.0'
],
entry_points={
'console_scripts': [


Loading…
Cancel
Save