Esempio n. 1
0
    def _registerClient(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        myOrgId = args["orgId"]

        name = utils.getRequestArg(request, "name")
        desc = utils.getRequestArg(request, "desc")
        scope = utils.getRequestArg(request, "scope", multiValued=True)
        category = utils.getRequestArg(request, "category")
        redirect = utils.getRequestArg(request, "redirect", sanitize=False)

        if not name:
            raise errors.MissingParams(["Name"])

        if not scope:
            raise errors.MissingParams(["Permissions"])

        if category != "apikey" and not redirect:
            raise errors.MissingParams(["Redirect URL"])

        knownScopes = globals().get("scopes")
        unknownScopes = [x for x in scope if x not in knownScopes.keys()]
        if category not in ["webapp", "native", "apikey"] or unknownScopes:
            raise errors.BaseError("Invalid value sent for Type/Permissions")

        clientId = utils.getUniqueKey()
        clientSecret = utils.getRandomKey()

        meta = {
            "author": myId,
            "name": name,
            "org": myOrgId,
            "secret": utils.hashpass(clientSecret),
            "scope": " ".join(scope),
            "category": category,
        }

        if category != "apikey":
            meta["redirect"] = b64encode(redirect)
            meta["desc"] = desc
            yield db.batch_insert(clientId, "apps", {"meta": meta})
            yield db.insert(myId, "appsByOwner", "", clientId)
            yield db.insert(myOrgId, "appsByOwner", "", clientId)
        else:
            yield db.batch_insert(clientId, "apps", {"meta": meta})
            yield db.insert(myId, "entities", "", clientId, "apikeys")

        self.setTitle(request, name)

        args["clientId"] = clientId
        args["client"] = meta
        args["client"]["secret"] = clientSecret
        t.renderScriptBlock(request, "apps.mako", "registrationResults", landing, "#apps-contents", "set", **args)
Esempio n. 2
0
    def _secret(self, request):
        myId = request.getSession(IAuthInfo).username
        clientId = utils.getRequestArg(request, "id", sanitize=False)

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client:
            raise errors.InvalidApp(clientId)

        if client["meta"]["author"] != myId:
            raise errors.AppAccessDenied(clientId)

        clientSecret = utils.getRandomKey()
        yield db.insert(clientId, "apps", utils.hashpass(clientSecret), "secret", "meta")

        args = {"clientId": clientId, "client": client["meta"], "info": "New application secret was generated"}
        args["client"]["secret"] = clientSecret
        t.renderScriptBlock(request, "apps.mako", "registrationResults", False, "#apps-contents", "set", **args)
Esempio n. 3
0
def _sendSignupInvitation(emailId):
    if len(emailId.split('@')) != 2:
        raise InvalidEmailId()

    mailId, domain = emailId.split('@')
    if domain in blacklist:
        raise DomainBlacklisted()

    rootUrl = config.get('General', 'URL')
    brandName = config.get('Branding', 'Name')
    signature = "Flocked-in Team.\n\n\n\n"

    myOrgId = yield getOrgId(domain)
    if myOrgId:
        entities = yield db.get_slice(myOrgId, "entities", ["basic"])
        myOrg = utils.supercolumnsToDict(entities)
        orgName = myOrg['basic']['name']
    else:
        orgName = domain

    existing = yield db.get_slice(emailId, "userAuth", ["user"])
    existing = utils.columnsToDict(existing)
    if existing and existing.get('user', ''):
        subject = "[%s] Account exists" % (brandName)
        body = "You already have an account on %(brandName)s.\n"\
               "Please visit %(rootUrl)s/signin to sign-in.\n\n"
        textBody = (body + signature) % locals()
        htmlBody = t.getBlock("emails.mako", "accountExists", **locals())
    else:
        subject = "Welcome to %s" % (brandName)
        body = "Please click the following link to join %(orgName)s network on %(brandName)s\n"\
               "%(activationUrl)s\n\n"
        activationTmpl = "%(rootUrl)s/signup?email=%(emailId)s&token=%(token)s"

        token = utils.getRandomKey()
        insert_d = db.insert(domain, "invitations", emailId, token, emailId)
        activationUrl = activationTmpl % locals()
        textBody = (body + signature) % locals()
        htmlBody = t.getBlock("emails.mako", "signup", **locals())
        yield insert_d

    yield utils.sendmail(emailId, subject, textBody, htmlBody)
Esempio n. 4
0
    def request_resetPassword(self, request):
        email = utils.getRequestArg(request, 'email')

        if not email:
            raise MissingParams([''])

        now = time.time()
        validEmail, tokens, deleteTokens, leastTimestamp = yield _getResetPasswordTokens(email)
        if len(tokens) >= 10:
            delta = datetime.fromtimestamp(leastTimestamp + 86399) - datetime.fromtimestamp(now)
            hours = 1 + delta.seconds / 3600
            raise PermissionDenied('We detected ususual activity from your account.<br/>  Click the link sent to your emailId to reset password or wait for %s hours before you retry' % (hours))

        if validEmail:
            token = utils.getRandomKey()
            yield db.insert(email, "userAuth", token, 'resetPasswdToken:%s' % (token), ttl=86400)
            yield _sendmailResetPassword(email, token)

        args = {"view": "forgotPassword-post"}
        t.render(request, "signup.mako", **args)
Esempio n. 5
0
    def _reportUser(self, request, myId, targetId):

        entities = base.EntitySet([myId, targetId])
        yield entities.fetchData()
        reportedBy = entities[myId].basic["name"]
        email = entities[targetId].basic["emailId"]
        rootUrl = config.get('General', 'URL')
        brandName = config.get('Branding', 'Name')
        authinfo = request.getSession(IAuthInfo)
        amIAdmin = authinfo.isAdmin

        cols = yield db.get_slice(email, "userAuth", ["reactivateToken",
                                                      "isFlagged", "isAdmin"])
        cols = utils.columnsToDict(cols)
        if cols.has_key("isAdmin") and not amIAdmin:
            raise errors.PermissionDenied("Only administrators can flag other \
                                            administrators for verification")

        if cols.has_key("isFlagged"):
            token = cols.get("reactivateToken")
        else:
            token = utils.getRandomKey()
            yield db.insert(email, "userAuth", token, 'reactivateToken')
            yield db.insert(email, "userAuth", "", 'isFlagged')

        body = "%(reportedBy)s has flagged your account for verification."\
               "You can verify your account by clicking on the link below.\n"\
               "\n\n%(reactivateUrl)s\n\n"

        reactivateUrl = "%(rootUrl)s/password/verify?email=%(email)s&token=%(token)s"%(locals())
        args = {"brandName": brandName, "rootUrl": rootUrl,
                "reportedBy":reportedBy, "reactivateUrl": reactivateUrl}
        subject = "[%(brandName)s] Your profile has been flagged for review" %(locals())
        htmlBody = t.getBlock("emails.mako", "reportUser", **args)
        textBody = body %(locals())

        yield utils.sendmail(email, subject, textBody, htmlBody)

        request.write('$$.alerts.info("%s");' % _('User has been flagged for verification'))
Esempio n. 6
0
    def _tokenForClientCredentials(self, request):
        clientId = utils.getRequestArg(request, 'client_id')
        clientSecret = utils.getRequestArg(request, 'client_secret')

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client or not utils.checkpass(clientSecret, client['meta']['secret']):
            self._error(request, "invalid_client")
            return

        # The client is valid.  Issue auth token.
        # We don't issue a refresh token and everytime the client will have
        # to authenticate using it's credentials
        scopes = client["meta"]["scope"].split(' ')
        userId = client["meta"]["author"]
        orgId  = client["meta"]["org"]
        accessToken = utils.getRandomKey()
        accessTokenData = {"user_id": userId, "type": "access", "org_id": orgId,
                           "client_id": clientId, "scope": " ".join(scopes)}
        yield db.batch_insert(accessToken, "oAuthData",
                              accessTokenData, ttl=self._accessTokenExpiry)
        self._success(request, accessToken)
Esempio n. 7
0
    def _receiveUserAccess(self, request):
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        myOrgId = authinfo.organization

        allow = utils.getRequestArg(request, 'allow') == "true"
        state = utils.getRequestArg(request, 'state')
        scopes = utils.getRequestArg(request, 'scope')
        clientId = utils.getRequestArg(request, 'client_id')
        redirectUri = utils.getRequestArg(request, 'redirect_uri', sanitize=False)
        signature = utils.getRequestArg(request, 'signature')

        # Check if signature is valid
        message = "%s:%s:%s:%s:%s" % \
                  (myId, clientId, scopes, redirectUri, state)
        checksum = hmac.new(myOrgId, message, hashlib.sha256)
        if signature != checksum.hexdigest():
            self._error(request, self.SIGNATURE_MISMATCH)
            return

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client:
            self._error(request, self.CLIENT_GONE)
            return

        if allow:
            # Authcode must expire shortly after it is issued
            # We expire the authcode in 5 minutes?
            authCode = utils.getRandomKey()
            authMap = {"user_id": myId, "org_id": myOrgId,
                       "client_id": clientId,
                       "redirect_uri": b64encode(redirectUri),
                       "scope": scopes, "type": "auth"}
            yield db.batch_insert(authCode, "oAuthData", authMap, ttl=120)
            yield db.insert(myId, "entities", authCode, clientId, "apps", ttl=120)
            self._redirectOnSuccess(request, redirectUri, authCode, state)
        else:
            self._redirectOnError(request, redirectUri, "access_denied", state)
Esempio n. 8
0
    def _tokenForAuthCode(self, request, refresh=False):
        clientId = utils.getRequestArg(request, 'client_id')
        clientSecret = utils.getRequestArg(request, 'client_secret')
        redirectUri = utils.getRequestArg(request, 'redirect_uri', sanitize=False)
        scopes = utils.getRequestArg(request, 'scope')

        if refresh:
            authCode = utils.getRequestArg(request, 'refresh_token')
        else:
            authCode = utils.getRequestArg(request, 'code')

        # XXX: We should be checking for HTTP authentication before
        #      throwing an error in case of missing clientId and clientSecret.
        if not all([redirectUri, clientId, clientSecret, authCode]):
            self._error(request, "invalid_request")
            return

        grant = yield db.get_slice(authCode, "oAuthData")
        grant = utils.columnsToDict(grant)
        if not grant or grant['client_id'] != clientId or\
           grant['redirect_uri'] != b64encode(redirectUri) or\
           not (grant['type'] == 'auth' and not refresh or\
                grant['type'] == 'refresh' and refresh):
            self._error(request, "invalid_grant")
            return

        grantedScopes = grant['scope'].split(' ')
        if scopes:
            scopes = scopes.split(' ')
            if [x for x in scopes if x not in grantedScopes]:
                self._error(request, "invalid_scope")
                return
        else:
            scopes = grantedScopes

        client = yield db.get_slice(clientId, "apps")
        client = utils.supercolumnsToDict(client)
        if not client or not utils.checkpass(clientSecret, client['meta']['secret']):
            self._error(request, "invalid_client")
            return

        userId = grant["user_id"]
        orgId  = grant["org_id"]
        accessToken = utils.getRandomKey()
        accessTokenData = {"user_id": userId, "org_id": orgId,
                           "type": "access", "client_id": clientId,
                           "auth_code": authCode, "scope": " ".join(scopes)}
        yield db.batch_insert(accessToken, "oAuthData",
                              accessTokenData, ttl=self._accessTokenExpiry)

        refreshToken = utils.getRandomKey()
        refreshTokenData = {"user_id": userId, "org_id": orgId,
                            "type": "refresh", "client_id": clientId,
                            "redirect_uri": grant["redirect_uri"],
                            "auth_code": authCode, "scope": grant["scope"]}
        yield db.batch_insert(refreshToken, "oAuthData",
                              refreshTokenData, ttl=self._refreshTokenExpiry)
        yield db.insert(userId, "entities", refreshToken, clientId,
                        "apps", ttl=self._refreshTokenExpiry)

        yield db.remove(authCode, "oAuthData")
        self._success(request, accessToken, refreshToken)
Esempio n. 9
0
def _sendInvitations(myOrgUsers, otherOrgUsers, me, myId, myOrg):
    rootUrl = config.get('General', 'URL')
    brandName = config.get('Branding', 'Name')
    senderName = me.basic["name"]
    senderOrgName = myOrg.basic["name"]
    senderAvatarUrl = utils.userAvatar(myId, me, "medium")
    sentUsers = []
    blockedUsers = []
    existingUsers = []

    myOrgSubject = "%s invited you to %s" % (senderName, brandName)
    myOrgBody = "Hi,\n\n"\
                "%(senderName)s has invited you to %(senderOrgName)s network on %(brandName)s.\n"\
                "To activate your account please visit: %(activationUrl)s.\n\n"
    otherOrgSubject = "%s invited you to %s" % (senderName, brandName)
    otherOrgBody = "Hi,\n\n"\
                   "%(senderName)s has invited you to try %(brandName)s.\n"\
                   "To activate your account please visit: %(activationUrl)s.\n\n"

    signature = "Flocked.in Team.\n\n\n\n"\
                "--\n"\
                "To block invitations from %(senderName)s visit %(blockSenderUrl)s\n"\
                "To block all invitations from %(brandName)s visit %(blockAllUrl)s"

    blockSenderTmpl = "%(rootUrl)s/signup/blockSender?email=%(emailId)s&token=%(token)s"
    blockAllTmpl = "%(rootUrl)s/signup/blockAll?email=%(emailId)s&token=%(token)s"
    activationTmpl = "%(rootUrl)s/signup?email=%(emailId)s&token=%(token)s"

    # Combine all users.
    myOrgUsers.extend(otherOrgUsers)

    # Ensure that the users do not already exist and that the users are
    # not in the doNotSpam list (for this sender or globally)
    d1 = db.multiget(myOrgUsers, "userAuth", "user")
    d2 = db.multiget_slice(myOrgUsers, "doNotSpam", [myId, '*'])
    existing = yield d1
    existing = utils.multiColumnsToDict(existing)
    doNotSpam = yield d2
    doNotSpam = utils.multiColumnsToDict(doNotSpam)

    deferreds = []
    for emailId in myOrgUsers:
        if emailId in existing and existing[emailId]:
            existingUsers.append(emailId)
            continue

        token = utils.getRandomKey()

        # Add invitation to the database
        localpart, domainpart = emailId.split('@')
        deferreds.append(db.insert(domainpart, "invitations", myId, token, emailId))
        deferreds.append(db.insert(myId, "invitationsSent", '', emailId))

        # Mail the invitation if everything is ok.
        if emailId in doNotSpam and doNotSpam[emailId]:
            blockedUsers.append(emailId)
            continue

        activationUrl = activationTmpl % locals()
        blockAllUrl = blockAllTmpl % locals()
        blockSenderUrl = blockSenderTmpl % locals()
        sameOrg = False if emailId in otherOrgUsers else True
        if not sameOrg:
            subject = otherOrgSubject
            textBody = (otherOrgBody + signature) % locals()
        else:
            subject = myOrgSubject
            textBody = (myOrgBody + signature) % locals()

        # XXX: getBlock blocks the application for disk reads when reading template
        htmlBody = t.getBlock("emails.mako", "invite", **locals())
        deferreds.append(utils.sendmail(emailId, subject, textBody, htmlBody))
        sentUsers.append(emailId)

    yield defer.DeferredList(deferreds)
    defer.returnValue((sentUsers, blockedUsers, existingUsers))