class OAuth2Token(sql.Model): """Data model for a bearer token used by a client.""" __tablename__ = 'oauth2_tokens' id = sql.Column(sql.Integer, primary_key=True) client_id = sql.Column(sql.String(40), sql.ForeignKey('oauth2_clients.client_id'), nullable=False) client = sql.relationship('OAuth2Client') user_id = sql.Column(sql.Integer, sql.ForeignKey('users.id')) user = sql.relationship('User') # Currently only bearer is supported. token_type = sql.Column(sql.String(40)) access_token = sql.Column(sql.String(255), unique=True) refresh_token = sql.Column(sql.String(255), unique=True) expires = sql.Column(sql.DateTime) _scopes = sql.Column(sql.Text) def delete(self): sql.session.delete(self) sql.session.commit() return self @property def scopes(self): if self._scopes: return self._scopes.split() return []
class OAuth2Grant(sql.Model): """Data model for a grant token created in the authorization flow.""" __tablename__ = 'oauth2_grants' id = sql.Column(sql.Integer, primary_key=True) user_id = sql.Column(sql.Integer, sql.ForeignKey('users.id')) user = sql.relationship('User') client_id = sql.Column(sql.String(40), sql.ForeignKey('oauth2_clients.client_id'), nullable=False) client = sql.relationship('OAuth2Client') code = sql.Column(sql.String(255), index=True, nullable=False) redirect_uri = sql.Column(sql.String(255)) expires = sql.Column(sql.DateTime) _scopes = sql.Column(sql.Text) def delete(self): sql.session.delete(self) sql.session.commit() return self @property def scopes(self): if self._scopes: return self._scopes.split() return []
class Target(db.Model): __tablename__ = 'tb_target' id = db.Column(db.Integer, primary_key=True) id_user = db.Column(db.Integer, db.ForeignKey('tb_user.id')) target_url = db.Column(db.String(50), nullable=False) target_server = db.Column(db.String(20)) target_country = db.Column(db.String(7)) target_status_code = db.Column(db.String(4)) submited_at = db.Column(db.Date, default=datetime.utcnow) revip = db.relationship('RevIP', backref='target', lazy='dynamic', cascade='all, delete') whois = db.relationship('Whois', backref='target', lazy='dynamic', cascade='all, delete') wpuser = db.relationship('WPUser', backref='target', lazy='dynamic', cascade='all, delete') foundlink = db.relationship('FoundLink', backref='target', lazy='dynamic', cascade='all, delete') dnslookup = db.relationship('DNSLookup', backref='target', lazy='dynamic', cascade='all, delete') def __init__(self, user, url=None): self.user = user self.target_url = url
class User(db.Model, UserMixin): __tablename__ = 'tb_user' id = db.Column(db.Integer, primary_key=True) id_role = db.Column(db.Integer, db.ForeignKey('tb_role.id')) real_name = db.Column(db.String(40), nullable=False, unique=True) user_name = db.Column(db.String(20), nullable=False, unique=True) pass_word = db.Column(db.String(63), nullable=False) target = db.relationship('Target', backref='user', lazy='dynamic', cascade='all, delete') def secure_password(self, plaintext): pass_salt = bcrypt.gensalt() pass_hash = bcrypt.hashpw(plaintext.encode('utf-8'), pass_salt) self.pass_word = pass_hash.decode('utf-8') def check_password(self, text_pass): return bcrypt.checkpw(text_pass.encode('utf-8'), self.pass_word.encode('utf-8')) def __init__(self, user_role, real_name, user_name): self.user_role = user_role self.real_name = real_name self.user_name = user_name
class WPUser(db.Model): __tablename__ = 'tb_wpuser' id = db.Column(db.Integer, primary_key=True) id_target = db.Column(db.Integer, db.ForeignKey('tb_target.id')) list_username = db.Column(JSON) def __init__(self, target, usernames=[]): self.target = target self.list_username = usernames
class RevIP(db.Model): __tablename__ = 'tb_revip' id = db.Column(db.Integer, primary_key=True) id_target = db.Column(db.Integer, db.ForeignKey('tb_target.id')) list_domain = db.Column(JSON) def __init__(self, target, domains=[]): self.target = target self.list_domain = domains
class FoundLink(db.Model): __tablename__ = 'tb_link' id = db.Column(db.Integer, primary_key=True) id_target = db.Column(db.Integer, db.ForeignKey('tb_target.id')) found_link = db.Column(JSON) def __init__(self, target, found_link=None): self.target = target self.found_link = found_link
class Whois(db.Model): __tablename__ = 'tb_whois' id = db.Column(db.Integer, primary_key=True) id_target = db.Column(db.Integer, db.ForeignKey('tb_target.id')) has_scanned = db.Column(db.Boolean, default=False) whois_result = db.Column(db.Text) def __init__(self, target, has_scanned=False, result=None): self.target = target self.has_scanned = has_scanned self.whois_result = result
class User(UserMixin, sql.Model): """Database model for a user.""" __tablename__ = 'users' id = sql.Column(sql.Integer, primary_key=True) username = sql.Column(sql.String(32), unique=True, index=True) email = sql.Column(sql.String(64), unique=True, index=True, nullable=False) init = sql.Column(sql.String(64), index=True, nullable=False) password_hash = sql.Column(sql.String(128), nullable=False) role_id = sql.Column(sql.Integer, sql.ForeignKey('roles.id'), server_default='0', nullable=False) registered_on = sql.Column(sql.DateTime, nullable=False) def __init__(self, **kwargs): super(User, self).__init__(**kwargs) if self.role is None: if self.email == current_app.config['_ADMIN']: self.role = Role.query.filter_by(permissions=0xff).first() if self.role is None: self.role = Role.query.filter_by(default=True).first() def __repr__(self): return '<User %r>' % self.username @staticmethod def insert_admin_user(): """Create the admin user and insert into the database.""" admin_user = User.query.filter_by(id=1).first() if admin_user is None: admin_user = User(username='******', email=current_app.config['_ADMIN'], init=current_app.config['_ADMIN'], password=current_app.config['_ADMIN_PASSWORD'], registered_on=datetime.now()) admin_user.role = Role.query.filter_by(permissions=0xff).first() sql.session.add(admin_user) sql.session.commit() @property @staticmethod def password(): """Password not exposed.""" raise AttributeError('password is not a readable attribute') @password.setter def password(self, password): """Generate hash based on password property.""" self.password_hash = generate_password_hash(password) def verify_password(self, password): """Check supplied string against password hash""" return check_password_hash(self.password_hash, password) def can(self, permissions): """Check user permissions.""" return self.role is not None and \ (self.role.permissions & permissions) == permissions def is_administrator(self): """Check user is administrator""" return self.can(Permission.ADMINISTER_SITE) def super_user(self): """Check if user is the site super user.""" return self.id == 1 def generate_security_token(self): """Generate a security token.""" serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) return serializer.dumps( self.email, salt=current_app.config['SECURITY_PASSWORD_SALT']) def confirm_security_token(self, token, max_age=3600): """Validate a security token.""" serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) try: self.email = serializer.loads( token, salt=current_app.config['SECURITY_PASSWORD_SALT'], max_age=max_age) except BadSignature: raise return self.email @staticmethod def confirm_password_reset_token(token, max_age=3600): """Validate password reset token.""" serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) try: email = serializer.loads( token, salt=current_app.config['SECURITY_PASSWORD_SALT'], max_age=max_age) except BadSignature: raise return email
class OAuth2Client(sql.Model): """Data model for an app that wants to use the resources of a user.""" __tablename__ = 'oauth2_clients' # Human readable name, not required. name = sql.Column(sql.String(40)) # Human readable description, not required. description = sql.Column(sql.String(400)) # Creator of the client, not required. user_id = sql.Column(sql.ForeignKey('users.id')) # Required if you need to support client credential. user = sql.relationship('User') client_id = sql.Column(sql.String(40), primary_key=True) client_secret = sql.Column(sql.String(55), unique=True, index=True, nullable=False) # Public or Confidential. is_confidential = sql.Column(sql.Boolean) _redirect_uris = sql.Column(sql.Text) _default_scopes = sql.Column(sql.Text) grants = sql.relationship('OAuth2Grant', cascade='all, delete-orphan') tokens = sql.relationship('OAuth2Token', cascade='all, delete-orphan') @property def client_type(self): if self.is_confidential: return 'confidential' return public @property def redirect_uris(self): if self._redirect_uris: return self._redirect_uris.split() return [] @property def default_redirect_uri(self): return self.redirect_uris[0] @property def default_scopes(self): if self._default_scopes: return self._default_scopes.split() return [] @staticmethod def generate_client_id(): chars = string.ascii_letters + string.digits return ''.join(chars[ord(os.urandom(1)) % len(chars)] for _ in range(15)) @staticmethod def generate_client_secret(): chars = string.ascii_letters + string.digits return ''.join(chars[ord(os.urandom(1)) % len(chars)] for _ in range(30))