Skip to content

Commit

Permalink
[+] First commit: Importing repo
Browse files Browse the repository at this point in the history
  • Loading branch information
fmount committed Dec 7, 2017
0 parents commit 5b4f09d
Show file tree
Hide file tree
Showing 19 changed files with 861 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.vim
*.pyc
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 Francesco Pantano

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
LINKS API
====
A pastebin service to upload/share in a simple and fast way files, pieces of code/configuration,
etc..
The service is presented as a restful set of APIs written using the python Flask restful framework.
Add to your bashrc/zshrc the magic _nopaste_ alias to start sharing your snippets:

alias nopaste = "curl -F c=@- https://IP:PORT/api/links"

The main features of this little webserver are the following:


* Upload a file

cat $FILE | curl -F file=@- http://localhost:5000/api/links

* Show an uploaded file:

curl -i http://localhost:5000/<URL>

* Show all the links present on the server (admin purposes: require authentication)

curl -i -u user:password -X GET http://localhost:5000/api/links

* Show the helper (with curl or in a web browser)

curl -i http://localhost:5000

* Show file metadata

curl -i http://localhost:5000/api/link/<ID>

* Delete a file

curl -i -u fmount:fmount -X DELETE http://localhost:5000/api/link/<ID>


* Drop all links (delete files and clear the db table) **REQUIRE AUTH**

curl -i -u fmount:fmount -X DELETE http://localhost:5000/api/links


USER API
===

* Create a user

curl -i -X POST -H "Content-Type: application/json" -d '{"username":"fmount","password":"wtf"}' http://localhost:5000/api/users



TESTS
===

* Massive file upload

while true; do for i in $(ls); do cat $i | curl -F file=@- http://localhost:5000/api/links; sleep 1; done; done

KNOWN ISSUES
===


TODO
===
* Make a file / link available for a predefined timeframe window, then it expires and it's not available anymore.
* Show/Delete user(s)
Empty file added __init__.py
Empty file.
114 changes: 114 additions & 0 deletions basicpastev2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env python

# -*- coding: utf-8 -*-

############################################################################
#
# Licensed under the MIT License (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of the License
# in the LICENSE file or at
#
# https://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# author: fmount <[email protected]>
# version: 0.1
# company: --
#
#############################################################################

from flask import Flask, Response, jsonify, abort, render_template, make_response, request
from flask_restful import Api, Resource, reqparse, fields, marshal
import logging
import os
import sqlite_middleware
from lib.resources.linksapi import Links, LinkAPI
from model import Link, User, Base
from lib.resources.userapi import UserAPI
import jinja2
import json
import uuid

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from utils.short_url import Shorturl
from utils import helper
from config import CONF

"""
Datamodel is made like this:
links: [
{
id: [ID],
url: [URL],
timestamp: [timestamp]
},
{
id: [ID],
url: [URL],
timestamp: [timestamp]
} ]
The main flask resource is implemented on the linksv2 and remaind to
the more generic model called Link (you can find it on the model.py)
"""

LOG = logging.getLogger(__name__)

app = Flask(__name__, static_folder="uploads", static_url_path="")
api = Api(app)


my_loader = jinja2.ChoiceLoader([
app.jinja_loader,
jinja2.FileSystemLoader('templates'),
])

app.jinja_loader = my_loader
engine = sqlite_middleware._init_engine(Base)


@app.errorhandler(400)
def bad_request(error):
return make_response(jsonify({'error': 'Bad request'}), 400)


@app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)


@app.route('/', methods=['GET'])
def home():
return make_response(render_template('home.html'))


@app.route('/<url>')
def show_me_thefile(url):
identifier = Shorturl.toBase10(url)
print("Resolved identifier: %s\n" % str(identifier))

Session = sessionmaker(bind=engine)
if sqlite_middleware._find_object(identifier, Session()) is None or not \
os.path.exists(CONF.default.upload_folder + "/" + url):
abort(404)

return helper.render((CONF.default.upload_folder + "/" + url), request.user_agent)


api.add_resource(Links, "/api/links")
api.add_resource(LinkAPI, "/api/link/<int:uuid>", endpoint="link")
api.add_resource(UserAPI, "/api/users", endpoint="users")



if __name__ == '__main__':
app.run(debug=True)
76 changes: 76 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env python

# -*- coding: utf-8 -*-

############################################################################
#
# Licensed under the MIT License (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of the License
# in the LICENSE file or at
#
# https://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# author: fmount <[email protected]>
# version: 0.1
# company: --
#
#############################################################################

from oslo_config import cfg

# Register the stanza
opt_default_group = cfg.OptGroup(name='default', \
title='Default Options')

opt_database_group = cfg.OptGroup(name='database', \
title='Database options')

# Register the options

default_opts = [

cfg.StrOpt('upload_folder', default='uploads',
help=('Where store/retrieve files')),

cfg.StrOpt('uri', default='http://localhost:5000',
help=('Endpoint of the flask webserver')),

cfg.BoolOpt('debug', default=False, \
help=('True enables, False disables debug mode'))
]

database_opts = [

cfg.StrOpt('dbname', default='weburl.db',
help=('The sqlalchemy database name')),

cfg.StrOpt('sql_engine_prefix', default='sqlite:///',
help=('Prefix of the connection stub for the db')),
]


CONF = cfg.CONF
CONF.register_group(opt_default_group)
CONF.register_opts(default_opts, opt_default_group)

CONF.register_group(opt_database_group)
CONF.register_opts(database_opts, opt_database_group)

CONF.default.host = CONF.default.uri.split(":")[1].split("//")[1]
CONF.default.port = CONF.default.uri.split(":")[2]



if __name__ == '__main__':
print(CONF.default.upload_folder)
#print(CONF.default.upload_folder)
#print(CONF.default.uri)
#print(CONF.default.debug)
#print(CONF.database.dbname)
#print(CONF.database.sql_engine_prefix)
9 changes: 9 additions & 0 deletions config/nopaste.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[default]
upload_folder="uploads"
uri="http://localhost:5000/"
debug=False


[database]
dbname="weburl.db"
sql_engine_prefix="sqlite:///"
Empty file added lib/__init__.py
Empty file.
Empty file added lib/resources/__init__.py
Empty file.
Loading

0 comments on commit 5b4f09d

Please sign in to comment.