Пример #1
0
func init() {
	var err error

	me, err = nerdz.NewUser(1)
	if err != nil {
		panic(fmt.Sprintf("No error should happen when create existing user, but got: %+v", err))
	}

	other, err = nerdz.NewUser(2)
	if err != nil {
		panic(fmt.Sprintf("No error should happen when create existing user, but got: %+v", err))
	}

	blacklisted, _ = nerdz.NewUser(5)
	withClosedProfile, _ = nerdz.NewUser(7)
}
Пример #2
0
// authorization is the authorization middleware for users.
// It checks the access_token in the Authorization header or the access_token query parameter
// On success sets "me" = *User (current logged user) and "accessData" = current access data
// into the context. Sets even the scopes variable, the sorted slice of scopes in accessData
func authorization() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			var accessToken string
			auth := c.Request().Header.Get("Authorization")
			if auth == "" {
				// Check if there's the parameter access_token in the URL
				// this makes the bearer authentication with websockets compatible with OAuth2
				accessToken = c.QueryParam("access_token")
				if accessToken == "" {
					return c.String(http.StatusUnauthorized, "access_token required")
				}
			} else {
				if !strings.HasPrefix(auth, "Bearer ") {
					return echo.ErrUnauthorized
				}
				ss := strings.Split(auth, " ")
				if len(ss) != 2 {
					return echo.ErrUnauthorized
				}
				accessToken = ss[1]
			}

			accessData, err := (&nerdz.OAuth2Storage{}).LoadAccess(accessToken)
			if err != nil {
				return c.String(http.StatusUnauthorized, err.Error())
			}

			// fetch current logged user and store it into the context
			me, err := nerdz.NewUser(accessData.UserData.(uint64))
			if err != nil {
				return c.String(http.StatusInternalServerError, err.Error())
			}
			c.Set("me", me)

			// store the Access Data into the context
			c.Set("accessData", accessData)
			scopes := strings.Split(accessData.Scope, " ")
			sort.Strings(scopes)

			// store the sorted Scopes using the full format
			// eg: if accepted scope is profile:read,write
			// save 2 entries: profile:read and profile:write
			// each saved scope is always in the format <name>:<read|,write>
			var fullScopes []string
			for _, s := range scopes {
				//parts[0] = <scope>, parts[1] = <rw>
				parts := strings.Split(s, ":")
				rw := strings.Split(parts[1], ",")
				for _, perm := range rw {
					fullScopes = append(fullScopes, parts[0]+":"+perm)
				}
			}
			c.Set("scopes", fullScopes)

			// let next handler handle the context
			return next(c)
		})
	}
}
Пример #3
0
func TestUnfollowUser(t *testing.T) {
	other, _ = nerdz.NewUser(3)
	t.Logf("User(%d) unfollows User(%d)", me.Counter, other.Counter)

	oldNumFollowers := len(other.NumericFollowers())

	if err := me.Unfollow(other); err != nil {
		t.Error(err)
	}

	newNumFollowers := len(other.NumericFollowers())

	if newNumFollowers != oldNumFollowers-1 {
		t.Fatalf("The follower isn't removed from the followers list! (old %d, new %d)", oldNumFollowers, newNumFollowers)
	}
}
Пример #4
0
func TestFollowUser(t *testing.T) {
	other, _ = nerdz.NewUser(3)

	t.Logf("User(%d) follows User(%d)", me.Counter, other.Counter)

	oldNumFollowers := len(other.NumericFollowers())

	if err := me.Follow(other); err != nil {
		t.Log("The user should correctly follow the other user but: ")
		t.Error(err)
	}

	if len(other.NumericFollowers()) != oldNumFollowers+1 {
		t.Log("There isn't a new follower for the user!")
		t.Error("No new follower")
	}
}
Пример #5
0
func TestPms(t *testing.T) {
	other, _ = nerdz.NewUser(2)
	t.Logf("User(%d) -pm-> User(%d)", me.Counter, other.Counter)
	// build a pm configuration in order to filter results
	pmConf := nerdz.NewPmConfig().WithDescOrder(true)

	pmList, err := me.Pms(other.Counter, pmConf)

	if err != nil {
		t.Errorf("Error trying to get pms between user(%s) and user(%s) - %v", me.Id(), other.Id(), err)
		return
	}

	t.Log("####### PMS  ########")

	for _, val := range *pmList {
		t.Logf("%+v", val)
	}

	t.Log("####################")

	pmConf = nerdz.NewPmConfig().WithOffset(2).WithLimit(4)

	pmListR, errR := me.Pms(other.Counter, pmConf)

	if errR != nil {
		t.Errorf("Error trying to get pms between user(%s) and user(%s) - %v", me.Id(), other.Id(), errR)
		return
	}

	t.Log("####### PMS between (2 - 4) ########")

	for _, val := range *pmListR {
		t.Logf("%+v", val)
	}

	t.Log("####################")

}
Пример #6
0
func TestPms(t *testing.T) {
	other, _ = nerdz.NewUser(2)
	t.Logf("User(%d) pm-> User(%d)", me.Counter, other.Counter)
	pmList, err := me.Pms(other.Counter, nerdz.PmsOptions{})

	if err != nil {
		t.Fatalf("Error trying to get pms between user(%d) and user(%d) - %v", me.ID(), other.ID(), err)
		return
	}
	if len(*pmList) != 9 {
		t.Fatalf("Expected 9 messages, but got: %d\n", len(*pmList))
	}

	// Delete
	if err = me.DeleteConversation(other.ID()); err != nil {
		t.Fatalf("Conversation between me and other should be removed, but got: %s", err.Error())
	}

	pmList, err = me.Pms(other.ID(), nerdz.PmsOptions{})
	if len(*pmList) != 0 {
		t.Fatalf("Conversation between me and other should be removed, but %d messages got instead", len(*pmList))
	}
}
Пример #7
0
// User extract "id" from the url parameter, parse it and returns
// the User if the "me" (in the context) user is allowed to see it.
// Otherwise returns an error
func User(userID string, c echo.Context) (*nerdz.User, error) {
	var id uint64
	var e error
	if id, e = strconv.ParseUint(c.Param(userID), 10, 64); e != nil {
		c.JSON(http.StatusBadRequest, &Response{
			HumanMessage: "Invalid user identifier specified",
			Message:      e.Error(),
			Status:       http.StatusBadRequest,
			Success:      false,
		})
		return nil, e
	}

	var user *nerdz.User
	if user, e = nerdz.NewUser(id); e != nil {
		c.JSON(http.StatusBadRequest, &Response{
			HumanMessage: "User does not exists",
			Message:      e.Error(),
			Status:       http.StatusBadRequest,
			Success:      false,
		})
		return nil, e
	}

	me := c.Get("me").(*nerdz.User)
	if !me.CanSee(user) {
		message := "You can't see the required profile"
		c.JSON(http.StatusUnauthorized, &Response{
			HumanMessage: message,
			Message:      message,
			Status:       http.StatusUnauthorized,
			Success:      false,
		})
		return nil, errors.New(message)
	}
	return user, nil
}
Пример #8
0
// Authorize is the action of GET /oauth2/authorize and POST /oauth2/authorize when authentication is required
func Authorize() echo.HandlerFunc {
	return func(c echo.Context) error {
		resp := oauth.NewResponse()
		defer resp.Close()

		if ar := oauth.HandleAuthorizeRequest(resp, c.Request()); ar != nil {
			if c.QueryParam("authorized") == "" || c.QueryParam("authorized_code") == "" {
				c.Redirect(http.StatusFound, fmt.Sprintf("%s/oauth2/authorize.php?client_id=%s&response_type=%s&redirect_uri=%s&scope=%s",
					nerdz.Configuration.NERDZURL().String(),
					url.QueryEscape(c.QueryParam("client_id")),
					url.QueryEscape(c.QueryParam("response_type")),
					url.QueryEscape(c.QueryParam("redirect_uri")),
					url.QueryEscape(c.QueryParam("scope"))))
				return nil
			} else {
				var e error
				var userID uint64
				if userID, e = strconv.ParseUint(c.QueryParam("authorized"), 10, 64); e != nil {
					return c.JSON(http.StatusInternalServerError, &rest.Response{
						HumanMessage: "Invalid authorized (user id) value",
						Message:      e.Error(),
						Status:       http.StatusInternalServerError,
						Success:      false,
					})
				}

				var user *nerdz.User
				if user, e = nerdz.NewUser(userID); e != nil {
					return c.JSON(http.StatusInternalServerError, &rest.Response{
						HumanMessage: "Problem retrieving specified user",
						Message:      e.Error(),
						Status:       http.StatusInternalServerError,
						Success:      false,
					})
				}
				sha1_sum := fmt.Sprintf("%x", sha1.Sum([]byte(user.Username+user.Password+user.Email)))
				if sha1_sum != c.QueryParam("authorized_code") {
					message := "Invalid authorization code"
					return c.JSON(http.StatusInternalServerError, &rest.Response{
						HumanMessage: message,
						Message:      message,
						Status:       http.StatusInternalServerError,
						Success:      false,
					})
				}

				ar.UserData = user.Counter
				ar.Authorized = true
				oauth.FinishAuthorizeRequest(resp, c.Request(), ar)
			}
		}

		if resp.IsError && resp.InternalError != nil {
			return c.JSON(http.StatusInternalServerError, &rest.Response{
				HumanMessage: "Internal Server error",
				Message:      resp.InternalError.Error(),
				Status:       http.StatusInternalServerError,
				Success:      false,
			})
		}

		return osin.OutputJSON(resp, c.Response(), c.Request())
	}
}
Пример #9
0
package examples

import (
	"fmt"
	"github.com/nerdzeu/nerdz-api/nerdz"
)

var (
	// Retrieves all the information about the user with ID 1
	// the second parameter, an error, is suppressed
	user, _ = nerdz.NewUser(1)
)

// prints all the friends information
func findFriends() {
	// user.Friends() returns a pointer to an array whose elements are User
	if friendsList := user.Friends(); friendsList != nil {
		fmt.Println("#### Friends ######")
		// Dereference the pointer
		for _, otherUser := range *friendsList {
			fmt.Printf("%+v", otherUser)
		}

		fmt.Println("##################")
	} else {
		fmt.Printf("User(%d) hasn't any friends", user.Counter)
	}

}